diff options
-rw-r--r-- | net/sunrpc/xprtrdma/frwr_ops.c | 20 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/rpc_rdma.c | 1 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 1 |
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 | */ | ||
157 | void 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) | |||
884 | out_err: | 884 | out_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 | */ |
551 | bool frwr_is_supported(struct ib_device *device); | 551 | bool frwr_is_supported(struct ib_device *device); |
552 | void frwr_reset(struct rpcrdma_req *req); | ||
552 | int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep); | 553 | int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep); |
553 | int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr); | 554 | int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr); |
554 | void frwr_release_mr(struct rpcrdma_mr *mr); | 555 | void frwr_release_mr(struct rpcrdma_mr *mr); |