svcrdma: Server-side support for rpcrdma_connect_private
Prepare to receive an RDMA-CM private message when handling a new connection attempt, and send a similar message as part of connection acceptance. Both sides can communicate their various implementation limits. Implementations that don't support this sideband protocol ignore it. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
5d48709656
commit
cc9d83408b
|
@ -648,6 +648,21 @@ int svc_rdma_repost_recv(struct svcxprt_rdma *xprt, gfp_t flags)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
svc_rdma_parse_connect_private(struct svcxprt_rdma *newxprt,
|
||||
struct rdma_conn_param *param)
|
||||
{
|
||||
const struct rpcrdma_connect_private *pmsg = param->private_data;
|
||||
|
||||
if (pmsg &&
|
||||
pmsg->cp_magic == rpcrdma_cmp_magic &&
|
||||
pmsg->cp_version == RPCRDMA_CMP_VERSION) {
|
||||
dprintk("svcrdma: client send_size %u, recv_size %u\n",
|
||||
rpcrdma_decode_buffer_size(pmsg->cp_send_size),
|
||||
rpcrdma_decode_buffer_size(pmsg->cp_recv_size));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the CONNECT_REQUEST event on a listening
|
||||
* endpoint. It is passed the cma_id for the _new_ connection. The context in
|
||||
|
@ -659,7 +674,8 @@ int svc_rdma_repost_recv(struct svcxprt_rdma *xprt, gfp_t flags)
|
|||
* will call the recvfrom method on the listen xprt which will accept the new
|
||||
* connection.
|
||||
*/
|
||||
static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird)
|
||||
static void handle_connect_req(struct rdma_cm_id *new_cma_id,
|
||||
struct rdma_conn_param *param)
|
||||
{
|
||||
struct svcxprt_rdma *listen_xprt = new_cma_id->context;
|
||||
struct svcxprt_rdma *newxprt;
|
||||
|
@ -675,9 +691,10 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird)
|
|||
new_cma_id->context = newxprt;
|
||||
dprintk("svcrdma: Creating newxprt=%p, cm_id=%p, listenxprt=%p\n",
|
||||
newxprt, newxprt->sc_cm_id, listen_xprt);
|
||||
svc_rdma_parse_connect_private(newxprt, param);
|
||||
|
||||
/* Save client advertised inbound read limit for use later in accept. */
|
||||
newxprt->sc_ord = client_ird;
|
||||
newxprt->sc_ord = param->initiator_depth;
|
||||
|
||||
/* Set the local and remote addresses in the transport */
|
||||
sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr;
|
||||
|
@ -712,8 +729,7 @@ static int rdma_listen_handler(struct rdma_cm_id *cma_id,
|
|||
dprintk("svcrdma: Connect request on cma_id=%p, xprt = %p, "
|
||||
"event = %s (%d)\n", cma_id, cma_id->context,
|
||||
rdma_event_msg(event->event), event->event);
|
||||
handle_connect_req(cma_id,
|
||||
event->param.conn.initiator_depth);
|
||||
handle_connect_req(cma_id, &event->param.conn);
|
||||
break;
|
||||
|
||||
case RDMA_CM_EVENT_ESTABLISHED:
|
||||
|
@ -947,6 +963,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
|
|||
struct svcxprt_rdma *listen_rdma;
|
||||
struct svcxprt_rdma *newxprt = NULL;
|
||||
struct rdma_conn_param conn_param;
|
||||
struct rpcrdma_connect_private pmsg;
|
||||
struct ib_qp_init_attr qp_attr;
|
||||
struct ib_device *dev;
|
||||
unsigned int i;
|
||||
|
@ -1100,11 +1117,20 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
|
|||
/* Swap out the handler */
|
||||
newxprt->sc_cm_id->event_handler = rdma_cma_handler;
|
||||
|
||||
/* Construct RDMA-CM private message */
|
||||
pmsg.cp_magic = rpcrdma_cmp_magic;
|
||||
pmsg.cp_version = RPCRDMA_CMP_VERSION;
|
||||
pmsg.cp_flags = 0;
|
||||
pmsg.cp_send_size = pmsg.cp_recv_size =
|
||||
rpcrdma_encode_buffer_size(newxprt->sc_max_req_size);
|
||||
|
||||
/* Accept Connection */
|
||||
set_bit(RDMAXPRT_CONN_PENDING, &newxprt->sc_flags);
|
||||
memset(&conn_param, 0, sizeof conn_param);
|
||||
conn_param.responder_resources = 0;
|
||||
conn_param.initiator_depth = newxprt->sc_ord;
|
||||
conn_param.private_data = &pmsg;
|
||||
conn_param.private_data_len = sizeof(pmsg);
|
||||
ret = rdma_accept(newxprt->sc_cm_id, &conn_param);
|
||||
if (ret) {
|
||||
dprintk("svcrdma: failed to accept new connection, ret=%d\n",
|
||||
|
|
Loading…
Reference in New Issue