xprtrdma: Release orphaned MRs immediately
authorChuck Lever <chuck.lever@oracle.com>
Wed, 29 Jun 2016 17:54:08 +0000 (13:54 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Mon, 11 Jul 2016 19:50:43 +0000 (15:50 -0400)
Instead of leaving orphaned MRs to be released when the transport
is destroyed, release them immediately. The MR free list can now be
replenished if it becomes exhausted.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Tested-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
net/sunrpc/xprtrdma/fmr_ops.c
net/sunrpc/xprtrdma/frwr_ops.c

index 758cd1a02249b5b36c3cab10db7a935d4ed8688e..6521dceff63863c5750d066a7a9d182b6e24ae62 100644 (file)
@@ -134,15 +134,22 @@ fmr_op_recover_mr(struct rpcrdma_mw *mw)
        /* ORDER: then DMA unmap */
        ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
                        mw->mw_sg, mw->mw_nents, mw->mw_dir);
-       if (rc) {
-               pr_err("rpcrdma: FMR reset status %d, %p orphaned\n",
-                      rc, mw);
-               r_xprt->rx_stats.mrs_orphaned++;
-               return;
-       }
+       if (rc)
+               goto out_release;
 
        rpcrdma_put_mw(r_xprt, mw);
        r_xprt->rx_stats.mrs_recovered++;
+       return;
+
+out_release:
+       pr_err("rpcrdma: FMR reset failed (%d), %p released\n", rc, mw);
+       r_xprt->rx_stats.mrs_orphaned++;
+
+       spin_lock(&r_xprt->rx_buf.rb_mwlock);
+       list_del(&mw->mw_all);
+       spin_unlock(&r_xprt->rx_buf.rb_mwlock);
+
+       fmr_op_release_mr(mw);
 }
 
 static int
index e77776bc5d59173ebdc6d86eb9e38672fd9d506f..f4c06c8ba6220d49f415274012f776602a34a7ee 100644 (file)
@@ -177,15 +177,22 @@ frwr_op_recover_mr(struct rpcrdma_mw *mw)
 
        rc = __frwr_reset_mr(ia, mw);
        ib_dma_unmap_sg(ia->ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir);
-       if (rc) {
-               pr_err("rpcrdma: FRMR reset status %d, %p orphaned\n",
-                      rc, mw);
-               r_xprt->rx_stats.mrs_orphaned++;
-               return;
-       }
+       if (rc)
+               goto out_release;
 
        rpcrdma_put_mw(r_xprt, mw);
        r_xprt->rx_stats.mrs_recovered++;
+       return;
+
+out_release:
+       pr_err("rpcrdma: FRMR reset failed %d, %p release\n", rc, mw);
+       r_xprt->rx_stats.mrs_orphaned++;
+
+       spin_lock(&r_xprt->rx_buf.rb_mwlock);
+       list_del(&mw->mw_all);
+       spin_unlock(&r_xprt->rx_buf.rb_mwlock);
+
+       frwr_op_release_mr(mw);
 }
 
 static int