aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2015-10-24 17:27:51 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2015-11-02 13:45:15 -0500
commit124fa17d3e33060fbb28e995a42c7f5c8b31b345 (patch)
tree9bceb1dfc478c07561ae44f3d07540ea79796fd5 /net
parentf531a5dbc451afb66e9d6c71a69e8358d1847969 (diff)
xprtrdma: Pre-allocate Work Requests for backchannel
Pre-allocate extra send and receive Work Requests needed to handle backchannel receives and sends. The transport doesn't know how many extra WRs to pre-allocate until the xprt_setup_backchannel() call, but that's long after the WRs are allocated during forechannel setup. So, use a fixed value for now. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Tested-By: Devesh Sharma <devesh.sharma@avagotech.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtrdma/backchannel.c4
-rw-r--r--net/sunrpc/xprtrdma/verbs.c14
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h10
3 files changed, 26 insertions, 2 deletions
diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c
index 3d01b328f777..3165ed639eec 100644
--- a/net/sunrpc/xprtrdma/backchannel.c
+++ b/net/sunrpc/xprtrdma/backchannel.c
@@ -125,6 +125,9 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs)
125 * Twice as many rpc_rqsts are prepared to ensure there is 125 * Twice as many rpc_rqsts are prepared to ensure there is
126 * always an rpc_rqst available as soon as a reply is sent. 126 * always an rpc_rqst available as soon as a reply is sent.
127 */ 127 */
128 if (reqs > RPCRDMA_BACKWARD_WRS >> 1)
129 goto out_err;
130
128 for (i = 0; i < (reqs << 1); i++) { 131 for (i = 0; i < (reqs << 1); i++) {
129 rqst = kzalloc(sizeof(*rqst), GFP_KERNEL); 132 rqst = kzalloc(sizeof(*rqst), GFP_KERNEL);
130 if (!rqst) { 133 if (!rqst) {
@@ -161,6 +164,7 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs)
161out_free: 164out_free:
162 xprt_rdma_bc_destroy(xprt, reqs); 165 xprt_rdma_bc_destroy(xprt, reqs);
163 166
167out_err:
164 pr_err("RPC: %s: setup backchannel transport failed\n", __func__); 168 pr_err("RPC: %s: setup backchannel transport failed\n", __func__);
165 return -ENOMEM; 169 return -ENOMEM;
166} 170}
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 7f0ed30fdc84..93883ffb86e0 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -568,6 +568,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
568 struct ib_device_attr *devattr = &ia->ri_devattr; 568 struct ib_device_attr *devattr = &ia->ri_devattr;
569 struct ib_cq *sendcq, *recvcq; 569 struct ib_cq *sendcq, *recvcq;
570 struct ib_cq_init_attr cq_attr = {}; 570 struct ib_cq_init_attr cq_attr = {};
571 unsigned int max_qp_wr;
571 int rc, err; 572 int rc, err;
572 573
573 if (devattr->max_sge < RPCRDMA_MAX_IOVS) { 574 if (devattr->max_sge < RPCRDMA_MAX_IOVS) {
@@ -576,18 +577,27 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
576 return -ENOMEM; 577 return -ENOMEM;
577 } 578 }
578 579
580 if (devattr->max_qp_wr <= RPCRDMA_BACKWARD_WRS) {
581 dprintk("RPC: %s: insufficient wqe's available\n",
582 __func__);
583 return -ENOMEM;
584 }
585 max_qp_wr = devattr->max_qp_wr - RPCRDMA_BACKWARD_WRS;
586
579 /* check provider's send/recv wr limits */ 587 /* check provider's send/recv wr limits */
580 if (cdata->max_requests > devattr->max_qp_wr) 588 if (cdata->max_requests > max_qp_wr)
581 cdata->max_requests = devattr->max_qp_wr; 589 cdata->max_requests = max_qp_wr;
582 590
583 ep->rep_attr.event_handler = rpcrdma_qp_async_error_upcall; 591 ep->rep_attr.event_handler = rpcrdma_qp_async_error_upcall;
584 ep->rep_attr.qp_context = ep; 592 ep->rep_attr.qp_context = ep;
585 ep->rep_attr.srq = NULL; 593 ep->rep_attr.srq = NULL;
586 ep->rep_attr.cap.max_send_wr = cdata->max_requests; 594 ep->rep_attr.cap.max_send_wr = cdata->max_requests;
595 ep->rep_attr.cap.max_send_wr += RPCRDMA_BACKWARD_WRS;
587 rc = ia->ri_ops->ro_open(ia, ep, cdata); 596 rc = ia->ri_ops->ro_open(ia, ep, cdata);
588 if (rc) 597 if (rc)
589 return rc; 598 return rc;
590 ep->rep_attr.cap.max_recv_wr = cdata->max_requests; 599 ep->rep_attr.cap.max_recv_wr = cdata->max_requests;
600 ep->rep_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS;
591 ep->rep_attr.cap.max_send_sge = RPCRDMA_MAX_IOVS; 601 ep->rep_attr.cap.max_send_sge = RPCRDMA_MAX_IOVS;
592 ep->rep_attr.cap.max_recv_sge = 1; 602 ep->rep_attr.cap.max_recv_sge = 1;
593 ep->rep_attr.cap.max_inline_data = 0; 603 ep->rep_attr.cap.max_inline_data = 0;
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 1eb86c79f4b9..55d2660df56a 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -101,6 +101,16 @@ struct rpcrdma_ep {
101 */ 101 */
102#define RPCRDMA_IGNORE_COMPLETION (0ULL) 102#define RPCRDMA_IGNORE_COMPLETION (0ULL)
103 103
104/* Pre-allocate extra Work Requests for handling backward receives
105 * and sends. This is a fixed value because the Work Queues are
106 * allocated when the forward channel is set up.
107 */
108#if defined(CONFIG_SUNRPC_BACKCHANNEL)
109#define RPCRDMA_BACKWARD_WRS (8)
110#else
111#define RPCRDMA_BACKWARD_WRS (0)
112#endif
113
104/* Registered buffer -- registered kmalloc'd memory for RDMA SEND/RECV 114/* Registered buffer -- registered kmalloc'd memory for RDMA SEND/RECV
105 * 115 *
106 * The below structure appears at the front of a large region of kmalloc'd 116 * The below structure appears at the front of a large region of kmalloc'd