Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Chuck Lever and committed by
J. Bruce Fields
cc9d8340 5d487096

+30 -4
+30 -4
net/sunrpc/xprtrdma/svc_rdma_transport.c
··· 648 648 return ret; 649 649 } 650 650 651 + static void 652 + svc_rdma_parse_connect_private(struct svcxprt_rdma *newxprt, 653 + struct rdma_conn_param *param) 654 + { 655 + const struct rpcrdma_connect_private *pmsg = param->private_data; 656 + 657 + if (pmsg && 658 + pmsg->cp_magic == rpcrdma_cmp_magic && 659 + pmsg->cp_version == RPCRDMA_CMP_VERSION) { 660 + dprintk("svcrdma: client send_size %u, recv_size %u\n", 661 + rpcrdma_decode_buffer_size(pmsg->cp_send_size), 662 + rpcrdma_decode_buffer_size(pmsg->cp_recv_size)); 663 + } 664 + } 665 + 651 666 /* 652 667 * This function handles the CONNECT_REQUEST event on a listening 653 668 * endpoint. It is passed the cma_id for the _new_ connection. The context in ··· 674 659 * will call the recvfrom method on the listen xprt which will accept the new 675 660 * connection. 676 661 */ 677 - static void handle_connect_req(struct rdma_cm_id *new_cma_id, size_t client_ird) 662 + static void handle_connect_req(struct rdma_cm_id *new_cma_id, 663 + struct rdma_conn_param *param) 678 664 { 679 665 struct svcxprt_rdma *listen_xprt = new_cma_id->context; 680 666 struct svcxprt_rdma *newxprt; ··· 691 675 new_cma_id->context = newxprt; 692 676 dprintk("svcrdma: Creating newxprt=%p, cm_id=%p, listenxprt=%p\n", 693 677 newxprt, newxprt->sc_cm_id, listen_xprt); 678 + svc_rdma_parse_connect_private(newxprt, param); 694 679 695 680 /* Save client advertised inbound read limit for use later in accept. */ 696 - newxprt->sc_ord = client_ird; 681 + newxprt->sc_ord = param->initiator_depth; 697 682 698 683 /* Set the local and remote addresses in the transport */ 699 684 sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr; ··· 729 712 dprintk("svcrdma: Connect request on cma_id=%p, xprt = %p, " 730 713 "event = %s (%d)\n", cma_id, cma_id->context, 731 714 rdma_event_msg(event->event), event->event); 732 - handle_connect_req(cma_id, 733 - event->param.conn.initiator_depth); 715 + handle_connect_req(cma_id, &event->param.conn); 734 716 break; 735 717 736 718 case RDMA_CM_EVENT_ESTABLISHED: ··· 963 947 struct svcxprt_rdma *listen_rdma; 964 948 struct svcxprt_rdma *newxprt = NULL; 965 949 struct rdma_conn_param conn_param; 950 + struct rpcrdma_connect_private pmsg; 966 951 struct ib_qp_init_attr qp_attr; 967 952 struct ib_device *dev; 968 953 unsigned int i; ··· 1117 1100 /* Swap out the handler */ 1118 1101 newxprt->sc_cm_id->event_handler = rdma_cma_handler; 1119 1102 1103 + /* Construct RDMA-CM private message */ 1104 + pmsg.cp_magic = rpcrdma_cmp_magic; 1105 + pmsg.cp_version = RPCRDMA_CMP_VERSION; 1106 + pmsg.cp_flags = 0; 1107 + pmsg.cp_send_size = pmsg.cp_recv_size = 1108 + rpcrdma_encode_buffer_size(newxprt->sc_max_req_size); 1109 + 1120 1110 /* Accept Connection */ 1121 1111 set_bit(RDMAXPRT_CONN_PENDING, &newxprt->sc_flags); 1122 1112 memset(&conn_param, 0, sizeof conn_param); 1123 1113 conn_param.responder_resources = 0; 1124 1114 conn_param.initiator_depth = newxprt->sc_ord; 1115 + conn_param.private_data = &pmsg; 1116 + conn_param.private_data_len = sizeof(pmsg); 1125 1117 ret = rdma_accept(newxprt->sc_cm_id, &conn_param); 1126 1118 if (ret) { 1127 1119 dprintk("svcrdma: failed to accept new connection, ret=%d\n",