Skip to content

Commit 467c967

Browse files
chuckleveramschuma-ntap
authored andcommitted
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 <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent e7104a2 commit 467c967

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

net/sunrpc/xprtrdma/transport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ xprt_rdma_send_request(struct rpc_task *task)
599599

600600
if (req->rl_niovs == 0)
601601
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)
603603
rc = rpcrdma_marshal_chunks(rqst, 0);
604604
if (rc < 0)
605605
goto failed_marshal;

net/sunrpc/xprtrdma/verbs.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#endif
6363

6464
static void rpcrdma_reset_frmrs(struct rpcrdma_ia *);
65+
static void rpcrdma_reset_fmrs(struct rpcrdma_ia *);
6566

6667
/*
6768
* internal functions
@@ -868,8 +869,19 @@ rpcrdma_ep_connect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
868869
rpcrdma_ep_disconnect(ep, ia);
869870
rpcrdma_flush_cqs(ep);
870871

871-
if (ia->ri_memreg_strategy == RPCRDMA_FRMR)
872+
switch (ia->ri_memreg_strategy) {
873+
case RPCRDMA_FRMR:
872874
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+
}
873885

874886
xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
875887
id = rpcrdma_create_id(xprt, ia,
@@ -1289,6 +1301,34 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
12891301
kfree(buf->rb_pool);
12901302
}
12911303

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+
*/
1309+
static void
1310+
rpcrdma_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+
12921332
/* After a disconnect, a flushed FAST_REG_MR can leave an FRMR in
12931333
* an unusable state. Find FRMRs in this state and dereg / reg
12941334
* each. FRMRs that are VALID and attached to an rpcrdma_req are

0 commit comments

Comments
 (0)