aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtrdma
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2014-11-08 20:14:29 -0500
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2014-11-25 13:39:20 -0500
commit467c9674bccc073684ee34f4bd205cf1b135d76e (patch)
treecefc907944bb2dcbefec1a7fbf7a4a2df1e775da /net/sunrpc/xprtrdma
parente7104a2a96069975d489c60a30564372c6273a85 (diff)
xprtrdma: unmap all FMRs during transport disconnect
When using RPCRDMA_MTHCAFMR memory registration, after a few transport disconnect / reconnect cycles, ib_map_phys_fmr() starts to return EINVAL because the provider has exhausted its map pool. Make sure that all FMRs are unmapped during transport disconnect, and that ->send_request remarshals them during an RPC retransmit. This resets the transport's MRs to ensure that none are leaked during a disconnect. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net/sunrpc/xprtrdma')
-rw-r--r--net/sunrpc/xprtrdma/transport.c2
-rw-r--r--net/sunrpc/xprtrdma/verbs.c42
2 files changed, 42 insertions, 2 deletions
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 6a4615dd0261..cfe9a810e6bc 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -599,7 +599,7 @@ xprt_rdma_send_request(struct rpc_task *task)
599 599
600 if (req->rl_niovs == 0) 600 if (req->rl_niovs == 0)
601 rc = rpcrdma_marshal_req(rqst); 601 rc = rpcrdma_marshal_req(rqst);
602 else if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR) 602 else if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_ALLPHYSICAL)
603 rc = rpcrdma_marshal_chunks(rqst, 0); 603 rc = rpcrdma_marshal_chunks(rqst, 0);
604 if (rc < 0) 604 if (rc < 0)
605 goto failed_marshal; 605 goto failed_marshal;
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index af45cf390126..3c88276090e3 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -62,6 +62,7 @@
62#endif 62#endif
63 63
64static void rpcrdma_reset_frmrs(struct rpcrdma_ia *); 64static void rpcrdma_reset_frmrs(struct rpcrdma_ia *);
65static void rpcrdma_reset_fmrs(struct rpcrdma_ia *);
65 66
66/* 67/*
67 * internal functions 68 * internal functions
@@ -868,8 +869,19 @@ retry:
868 rpcrdma_ep_disconnect(ep, ia); 869 rpcrdma_ep_disconnect(ep, ia);
869 rpcrdma_flush_cqs(ep); 870 rpcrdma_flush_cqs(ep);
870 871
871 if (ia->ri_memreg_strategy == RPCRDMA_FRMR) 872 switch (ia->ri_memreg_strategy) {
873 case RPCRDMA_FRMR:
872 rpcrdma_reset_frmrs(ia); 874 rpcrdma_reset_frmrs(ia);
875 break;
876 case RPCRDMA_MTHCAFMR:
877 rpcrdma_reset_fmrs(ia);
878 break;
879 case RPCRDMA_ALLPHYSICAL:
880 break;
881 default:
882 rc = -EIO;
883 goto out;
884 }
873 885
874 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia); 886 xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
875 id = rpcrdma_create_id(xprt, ia, 887 id = rpcrdma_create_id(xprt, ia,
@@ -1289,6 +1301,34 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
1289 kfree(buf->rb_pool); 1301 kfree(buf->rb_pool);
1290} 1302}
1291 1303
1304/* After a disconnect, unmap all FMRs.
1305 *
1306 * This is invoked only in the transport connect worker in order
1307 * to serialize with rpcrdma_register_fmr_external().
1308 */
1309static void
1310rpcrdma_reset_fmrs(struct rpcrdma_ia *ia)
1311{
1312 struct rpcrdma_xprt *r_xprt =
1313 container_of(ia, struct rpcrdma_xprt, rx_ia);
1314 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
1315 struct list_head *pos;
1316 struct rpcrdma_mw *r;
1317 LIST_HEAD(l);
1318 int rc;
1319
1320 list_for_each(pos, &buf->rb_all) {
1321 r = list_entry(pos, struct rpcrdma_mw, mw_all);
1322
1323 INIT_LIST_HEAD(&l);
1324 list_add(&r->r.fmr->list, &l);
1325 rc = ib_unmap_fmr(&l);
1326 if (rc)
1327 dprintk("RPC: %s: ib_unmap_fmr failed %i\n",
1328 __func__, rc);
1329 }
1330}
1331
1292/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in 1332/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in
1293 * an unusable state. Find FRMRs in this state and dereg / reg 1333 * an unusable state. Find FRMRs in this state and dereg / reg
1294 * each. FRMRs that are VALID and attached to an rpcrdma_req are 1334 * each. FRMRs that are VALID and attached to an rpcrdma_req are