svcrdma: Server-side support for rpcrdma_connect_private
authorChuck Lever <chuck.lever@oracle.com>
Tue, 13 Sep 2016 14:53:15 +0000 (10:53 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 23 Sep 2016 14:18:54 +0000 (10:18 -0400)
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>
net/sunrpc/xprtrdma/svc_rdma_transport.c

index 924271c..f51e98a 100644 (file)
@@ -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",