aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2017-06-08 11:53:08 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2017-07-13 16:00:13 -0400
commite2f6ef09156284e35f780be47559809753d4b499 (patch)
treebc771a0ca1399bd07292a81e67b7318b86001441
parent173b8f49b3af3d5102168793436dc17b94476b74 (diff)
xprtrdma: FMR does not need list_del_init()
Clean up. Commit 38f1932e60ba ("xprtrdma: Remove FMRs from the unmap list after unmapping") utilized list_del_init() to try to prevent some list corruption. The corruption was actually caused by the reply handler racing with a signal. Now that MR invalidation is properly serialized, list_del_init() can safely be replaced. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--net/sunrpc/xprtrdma/fmr_ops.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c
index 2f4eacdde3f2..d3f84bb1d443 100644
--- a/net/sunrpc/xprtrdma/fmr_ops.c
+++ b/net/sunrpc/xprtrdma/fmr_ops.c
@@ -91,7 +91,7 @@ __fmr_unmap(struct rpcrdma_mw *mw)
91 91
92 list_add(&mw->fmr.fm_mr->list, &l); 92 list_add(&mw->fmr.fm_mr->list, &l);
93 rc = ib_unmap_fmr(&l); 93 rc = ib_unmap_fmr(&l);
94 list_del_init(&mw->fmr.fm_mr->list); 94 list_del(&mw->fmr.fm_mr->list);
95 return rc; 95 return rc;
96} 96}
97 97
@@ -261,7 +261,7 @@ out_maperr:
261static void 261static void
262fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mws) 262fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mws)
263{ 263{
264 struct rpcrdma_mw *mw, *tmp; 264 struct rpcrdma_mw *mw;
265 LIST_HEAD(unmap_list); 265 LIST_HEAD(unmap_list);
266 int rc; 266 int rc;
267 267
@@ -283,9 +283,11 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mws)
283 /* ORDER: Now DMA unmap all of the req's MRs, and return 283 /* ORDER: Now DMA unmap all of the req's MRs, and return
284 * them to the free MW list. 284 * them to the free MW list.
285 */ 285 */
286 list_for_each_entry_safe(mw, tmp, mws, mw_list) { 286 while (!list_empty(mws)) {
287 list_del_init(&mw->mw_list); 287 mw = rpcrdma_pop_mw(mws);
288 list_del_init(&mw->fmr.fm_mr->list); 288 dprintk("RPC: %s: DMA unmapping fmr %p\n",
289 __func__, &mw->fmr);
290 list_del(&mw->fmr.fm_mr->list);
289 ib_dma_unmap_sg(r_xprt->rx_ia.ri_device, 291 ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
290 mw->mw_sg, mw->mw_nents, mw->mw_dir); 292 mw->mw_sg, mw->mw_nents, mw->mw_dir);
291 rpcrdma_put_mw(r_xprt, mw); 293 rpcrdma_put_mw(r_xprt, mw);
@@ -296,9 +298,9 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mws)
296out_reset: 298out_reset:
297 pr_err("rpcrdma: ib_unmap_fmr failed (%i)\n", rc); 299 pr_err("rpcrdma: ib_unmap_fmr failed (%i)\n", rc);
298 300
299 list_for_each_entry_safe(mw, tmp, mws, mw_list) { 301 while (!list_empty(mws)) {
300 list_del_init(&mw->mw_list); 302 mw = rpcrdma_pop_mw(mws);
301 list_del_init(&mw->fmr.fm_mr->list); 303 list_del(&mw->fmr.fm_mr->list);
302 fmr_op_recover_mr(mw); 304 fmr_op_recover_mr(mw);
303 } 305 }
304} 306}