]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
xprtrdma: Add mechanism to place MRs back on the free list
authorChuck Lever <chuck.lever@oracle.com>
Wed, 19 Jun 2019 14:33:04 +0000 (10:33 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 9 Jul 2019 14:30:25 +0000 (10:30 -0400)
When a marshal operation fails, any MRs that were already set up for
that request are recycled. Recycling releases MRs and creates new
ones, which is expensive.

Since commit f2877623082b ("xprtrdma: Chain Send to FastReg WRs")
was merged, recycling FRWRs is unnecessary. This is because before
that commit, frwr_map had already posted FAST_REG Work Requests,
so ownership of the MRs had already been passed to the NIC and thus
dealing with them had to be delayed until they completed.

Since that commit, however, FAST_REG WRs are posted at the same time
as the Send WR. This means that if marshaling fails, we are certain
the MRs are safe to simply unmap and place back on the free list
because neither the Send nor the FAST_REG WRs have been posted yet.
The kernel still has ownership of the MRs at this point.

This reduces the total number of MRs that the xprt has to create
under heavy workloads and makes the marshaling logic less brittle.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/xprt_rdma.h

index 5c480bc1307587cad3ff92d7bd1791693a766801..524cac0a071563844962c8b139b4ff5fb29e6f8b 100644 (file)
@@ -144,6 +144,26 @@ frwr_mr_recycle_worker(struct work_struct *work)
        frwr_release_mr(mr);
 }
 
+/* frwr_reset - Place MRs back on the free list
+ * @req: request to reset
+ *
+ * Used after a failed marshal. For FRWR, this means the MRs
+ * don't have to be fully released and recreated.
+ *
+ * NB: This is safe only as long as none of @req's MRs are
+ * involved with an ongoing asynchronous FAST_REG or LOCAL_INV
+ * Work Request.
+ */
+void frwr_reset(struct rpcrdma_req *req)
+{
+       while (!list_empty(&req->rl_registered)) {
+               struct rpcrdma_mr *mr;
+
+               mr = rpcrdma_mr_pop(&req->rl_registered);
+               rpcrdma_mr_unmap_and_put(mr);
+       }
+}
+
 /**
  * frwr_init_mr - Initialize one MR
  * @ia: interface adapter
index f23450b176dd1b15ce83c8bd3ea74e497991c64d..67d72d68ca6ca8a87f7669efc63f1489c37ec927 100644 (file)
@@ -884,6 +884,7 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
 out_err:
        trace_xprtrdma_marshal_failed(rqst, ret);
        r_xprt->rx_stats.failed_marshal_count++;
+       frwr_reset(req);
        return ret;
 }
 
index a9de116a5c1a6650dacf4bc6a2c6e9a830f9dea9..a396528843085d1be3bf48225a33d8f30c77d342 100644 (file)
@@ -549,6 +549,7 @@ rpcrdma_data_dir(bool writing)
 /* Memory registration calls xprtrdma/frwr_ops.c
  */
 bool frwr_is_supported(struct ib_device *device);
+void frwr_reset(struct rpcrdma_req *req);
 int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep);
 int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr);
 void frwr_release_mr(struct rpcrdma_mr *mr);