diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2017-06-08 11:53:08 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2017-07-13 16:00:13 -0400 |
commit | e2f6ef09156284e35f780be47559809753d4b499 (patch) | |
tree | bc771a0ca1399bd07292a81e67b7318b86001441 | |
parent | 173b8f49b3af3d5102168793436dc17b94476b74 (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.c | 18 |
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: | |||
261 | static void | 261 | static void |
262 | fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mws) | 262 | fmr_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) | |||
296 | out_reset: | 298 | out_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 | } |