diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2015-10-24 17:27:51 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2015-11-02 13:45:15 -0500 |
commit | 124fa17d3e33060fbb28e995a42c7f5c8b31b345 (patch) | |
tree | 9bceb1dfc478c07561ae44f3d07540ea79796fd5 /net | |
parent | f531a5dbc451afb66e9d6c71a69e8358d1847969 (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.c | 4 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 14 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 10 |
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) | |||
161 | out_free: | 164 | out_free: |
162 | xprt_rdma_bc_destroy(xprt, reqs); | 165 | xprt_rdma_bc_destroy(xprt, reqs); |
163 | 166 | ||
167 | out_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 |