aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTom Tucker <tom@opengridcomputing.com>2008-05-07 14:52:42 -0400
committerTom Tucker <tom@opengridcomputing.com>2008-05-19 08:34:00 -0400
commitaf261af4db14230fb35bcdc0ba9ef78ed6cf7bc1 (patch)
tree1d9de4ac4a71f6fd79eb41e9244f34daf863790a /net
parent69500c43b45f7155b72dcadad31cd55cda789c93 (diff)
svcrdma: Copy transport address and arm CQ before calling rdma_accept
This race was found by inspection. Messages can be received from the peer immediately following the rdma_accept call, however, the CQ have not yet been armed and the transport address has not yet been set. Set the transport address in the connect request handler and arm the CQ prior to calling rdma_accept. Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 0b72c4c7d7cb..c7545203f4b3 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -570,6 +570,7 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id)
570{ 570{
571 struct svcxprt_rdma *listen_xprt = new_cma_id->context; 571 struct svcxprt_rdma *listen_xprt = new_cma_id->context;
572 struct svcxprt_rdma *newxprt; 572 struct svcxprt_rdma *newxprt;
573 struct sockaddr *sa;
573 574
574 /* Create a new transport */ 575 /* Create a new transport */
575 newxprt = rdma_create_xprt(listen_xprt->sc_xprt.xpt_server, 0); 576 newxprt = rdma_create_xprt(listen_xprt->sc_xprt.xpt_server, 0);
@@ -582,6 +583,12 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id)
582 dprintk("svcrdma: Creating newxprt=%p, cm_id=%p, listenxprt=%p\n", 583 dprintk("svcrdma: Creating newxprt=%p, cm_id=%p, listenxprt=%p\n",
583 newxprt, newxprt->sc_cm_id, listen_xprt); 584 newxprt, newxprt->sc_cm_id, listen_xprt);
584 585
586 /* Set the local and remote addresses in the transport */
587 sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr;
588 svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa));
589 sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr;
590 svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa));
591
585 /* 592 /*
586 * Enqueue the new transport on the accept queue of the listening 593 * Enqueue the new transport on the accept queue of the listening
587 * transport 594 * transport
@@ -750,7 +757,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
750 struct rdma_conn_param conn_param; 757 struct rdma_conn_param conn_param;
751 struct ib_qp_init_attr qp_attr; 758 struct ib_qp_init_attr qp_attr;
752 struct ib_device_attr devattr; 759 struct ib_device_attr devattr;
753 struct sockaddr *sa;
754 int ret; 760 int ret;
755 int i; 761 int i;
756 762
@@ -883,6 +889,13 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
883 /* Swap out the handler */ 889 /* Swap out the handler */
884 newxprt->sc_cm_id->event_handler = rdma_cma_handler; 890 newxprt->sc_cm_id->event_handler = rdma_cma_handler;
885 891
892 /*
893 * Arm the CQs for the SQ and RQ before accepting so we can't
894 * miss the first message
895 */
896 ib_req_notify_cq(newxprt->sc_sq_cq, IB_CQ_NEXT_COMP);
897 ib_req_notify_cq(newxprt->sc_rq_cq, IB_CQ_NEXT_COMP);
898
886 /* Accept Connection */ 899 /* Accept Connection */
887 set_bit(RDMAXPRT_CONN_PENDING, &newxprt->sc_flags); 900 set_bit(RDMAXPRT_CONN_PENDING, &newxprt->sc_flags);
888 memset(&conn_param, 0, sizeof conn_param); 901 memset(&conn_param, 0, sizeof conn_param);
@@ -919,14 +932,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
919 newxprt->sc_max_requests, 932 newxprt->sc_max_requests,
920 newxprt->sc_ord); 933 newxprt->sc_ord);
921 934
922 /* Set the local and remote addresses in the transport */
923 sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr;
924 svc_xprt_set_remote(&newxprt->sc_xprt, sa, svc_addr_len(sa));
925 sa = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr;
926 svc_xprt_set_local(&newxprt->sc_xprt, sa, svc_addr_len(sa));
927
928 ib_req_notify_cq(newxprt->sc_sq_cq, IB_CQ_NEXT_COMP);
929 ib_req_notify_cq(newxprt->sc_rq_cq, IB_CQ_NEXT_COMP);
930 return &newxprt->sc_xprt; 935 return &newxprt->sc_xprt;
931 936
932 errout: 937 errout: