svcrdma: Limit RQ depth
authorChuck Lever <chuck.lever@oracle.com>
Mon, 28 Aug 2017 19:06:06 +0000 (15:06 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Tue, 5 Sep 2017 19:15:30 +0000 (15:15 -0400)
Ensure that the chosen Receive Queue depth for a newly created
transport does not overrun the QP WR limit of the underlying device.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
net/sunrpc/xprtrdma/svc_rdma_transport.c

index 2aa8473dcc97dafdc63f3ea4dd3034fdf238932c..cdb04f8a0c250c19a0dd816eed55f0b8512a8b9e 100644 (file)
@@ -167,8 +167,8 @@ static bool svc_rdma_prealloc_ctxts(struct svcxprt_rdma *xprt)
 {
        unsigned int i;
 
-       /* Each RPC/RDMA credit can consume a number of send
-        * and receive WQEs. One ctxt is allocated for each.
+       /* Each RPC/RDMA credit can consume one Receive and
+        * one Send WQE at the same time.
         */
        i = xprt->sc_sq_depth + xprt->sc_rq_depth;
 
@@ -742,13 +742,18 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
        newxprt->sc_max_sge = min((size_t)dev->attrs.max_sge,
                                  (size_t)RPCSVC_MAXPAGES);
        newxprt->sc_max_req_size = svcrdma_max_req_size;
-       newxprt->sc_max_requests = min_t(u32, dev->attrs.max_qp_wr,
-                                        svcrdma_max_requests);
-       newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests);
-       newxprt->sc_max_bc_requests = min_t(u32, dev->attrs.max_qp_wr,
-                                           svcrdma_max_bc_requests);
+       newxprt->sc_max_requests = svcrdma_max_requests;
+       newxprt->sc_max_bc_requests = svcrdma_max_bc_requests;
        newxprt->sc_rq_depth = newxprt->sc_max_requests +
                               newxprt->sc_max_bc_requests;
+       if (newxprt->sc_rq_depth > dev->attrs.max_qp_wr) {
+               pr_warn("svcrdma: reducing receive depth to %d\n",
+                       dev->attrs.max_qp_wr);
+               newxprt->sc_rq_depth = dev->attrs.max_qp_wr;
+               newxprt->sc_max_requests = newxprt->sc_rq_depth - 2;
+               newxprt->sc_max_bc_requests = 2;
+       }
+       newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests);
        newxprt->sc_sq_depth = newxprt->sc_rq_depth;
        atomic_set(&newxprt->sc_sq_avail, newxprt->sc_sq_depth);