summaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2019-06-19 10:33:04 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2019-07-09 10:30:25 -0400
commit40088f0e9b62d7fa033918b54ef45f8bf7d1ad1c (patch)
tree2fe9d38dcff3448adf8861089e0cde2081d7d82c /net/sunrpc
parent847568942f93e0af77e4bb8a098899f310cb3a88 (diff)
xprtrdma: Add mechanism to place MRs back on the free list
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>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/xprtrdma/frwr_ops.c20
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c1
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h1
3 files changed, 22 insertions, 0 deletions
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
index 5c480bc13075..524cac0a0715 100644
--- a/net/sunrpc/xprtrdma/frwr_ops.c
+++ b/net/sunrpc/xprtrdma/frwr_ops.c
@@ -144,6 +144,26 @@ frwr_mr_recycle_worker(struct work_struct *work)
144 frwr_release_mr(mr); 144 frwr_release_mr(mr);
145} 145}
146 146
147/* frwr_reset - Place MRs back on the free list
148 * @req: request to reset
149 *
150 * Used after a failed marshal. For FRWR, this means the MRs
151 * don't have to be fully released and recreated.
152 *
153 * NB: This is safe only as long as none of @req's MRs are
154 * involved with an ongoing asynchronous FAST_REG or LOCAL_INV
155 * Work Request.
156 */
157void frwr_reset(struct rpcrdma_req *req)
158{
159 while (!list_empty(&req->rl_registered)) {
160 struct rpcrdma_mr *mr;
161
162 mr = rpcrdma_mr_pop(&req->rl_registered);
163 rpcrdma_mr_unmap_and_put(mr);
164 }
165}
166
147/** 167/**
148 * frwr_init_mr - Initialize one MR 168 * frwr_init_mr - Initialize one MR
149 * @ia: interface adapter 169 * @ia: interface adapter
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index f23450b176dd..67d72d68ca6c 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -884,6 +884,7 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
884out_err: 884out_err:
885 trace_xprtrdma_marshal_failed(rqst, ret); 885 trace_xprtrdma_marshal_failed(rqst, ret);
886 r_xprt->rx_stats.failed_marshal_count++; 886 r_xprt->rx_stats.failed_marshal_count++;
887 frwr_reset(req);
887 return ret; 888 return ret;
888} 889}
889 890
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index a9de116a5c1a..a39652884308 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -549,6 +549,7 @@ rpcrdma_data_dir(bool writing)
549/* Memory registration calls xprtrdma/frwr_ops.c 549/* Memory registration calls xprtrdma/frwr_ops.c
550 */ 550 */
551bool frwr_is_supported(struct ib_device *device); 551bool frwr_is_supported(struct ib_device *device);
552void frwr_reset(struct rpcrdma_req *req);
552int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep); 553int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep);
553int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr); 554int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr);
554void frwr_release_mr(struct rpcrdma_mr *mr); 555void frwr_release_mr(struct rpcrdma_mr *mr);