rpcrdma: Fix SQ size calculation when memreg is FRMR
authorTom Tucker <tom@ogc.us>
Wed, 11 Aug 2010 16:47:24 +0000 (12:47 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 11 Aug 2010 16:47:24 +0000 (12:47 -0400)
This patch updates the computation to include the worst case situation
where three FRMR are required to map a single RPC REQ.

Signed-off-by: Tom Tucker <tom@ogc.us>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/verbs.c

index e5e28d1946a41a852a558caa83ca49c68265bed7..2ac3f6e8adffaf74a7480961997bb9fb97201e98 100644 (file)
@@ -249,6 +249,8 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
        req->rl_nchunks = nchunks;
 
        BUG_ON(nchunks == 0);
+       BUG_ON((r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
+              && (nchunks > 3));
 
        /*
         * finish off header. If write, marshal discrim and nchunks.
index 3bdbd9f3b88f9d9b593bf60dfed8affcca126bcc..5f4c7b3bc7114c597703c2739a427815c3be741c 100644 (file)
@@ -650,10 +650,22 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
        ep->rep_attr.cap.max_send_wr = cdata->max_requests;
        switch (ia->ri_memreg_strategy) {
        case RPCRDMA_FRMR:
-               /* Add room for frmr register and invalidate WRs */
-               ep->rep_attr.cap.max_send_wr *= 3;
-               if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
-                       return -EINVAL;
+               /* Add room for frmr register and invalidate WRs.
+                * 1. FRMR reg WR for head
+                * 2. FRMR invalidate WR for head
+                * 3. FRMR reg WR for pagelist
+                * 4. FRMR invalidate WR for pagelist
+                * 5. FRMR reg WR for tail
+                * 6. FRMR invalidate WR for tail
+                * 7. The RDMA_SEND WR
+                */
+               ep->rep_attr.cap.max_send_wr *= 7;
+               if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr) {
+                       cdata->max_requests = devattr.max_qp_wr / 7;
+                       if (!cdata->max_requests)
+                               return -EINVAL;
+                       ep->rep_attr.cap.max_send_wr = cdata->max_requests * 7;
+               }
                break;
        case RPCRDMA_MEMWINDOWS_ASYNC:
        case RPCRDMA_MEMWINDOWS: