Skip to content

Commit b45ccfd

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Remove MEMWINDOWS registration modes
The MEMWINDOWS and MEMWINDOWS_ASYNC memory registration modes were intended as stop-gap modes before the introduction of FRMR. They are now considered obsolete. MEMWINDOWS_ASYNC is also considered unsafe because it can leave client memory registered and exposed for an indeterminant time after each I/O. At this point, the MEMWINDOWS modes add needless complexity, so remove them. 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>
1 parent 03ff882 commit b45ccfd

File tree

4 files changed

+7
-203
lines changed

4 files changed

+7
-203
lines changed

net/sunrpc/xprtrdma/rpc_rdma.c

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
199199
return 0;
200200

201201
do {
202-
/* bind/register the memory, then build chunk from result. */
203202
int n = rpcrdma_register_external(seg, nsegs,
204203
cur_wchunk != NULL, r_xprt);
205204
if (n <= 0)
@@ -697,16 +696,6 @@ rpcrdma_conn_func(struct rpcrdma_ep *ep)
697696
schedule_delayed_work(&ep->rep_connect_worker, 0);
698697
}
699698

700-
/*
701-
* This function is called when memory window unbind which we are waiting
702-
* for completes. Just use rr_func (zeroed by upcall) to signal completion.
703-
*/
704-
static void
705-
rpcrdma_unbind_func(struct rpcrdma_rep *rep)
706-
{
707-
wake_up(&rep->rr_unbind);
708-
}
709-
710699
/*
711700
* Called as a tasklet to do req/reply match and complete a request
712701
* Errors must result in the RPC task either being awakened, or
@@ -721,7 +710,7 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep)
721710
struct rpc_xprt *xprt = rep->rr_xprt;
722711
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
723712
__be32 *iptr;
724-
int i, rdmalen, status;
713+
int rdmalen, status;
725714

726715
/* Check status. If bad, signal disconnect and return rep to pool */
727716
if (rep->rr_len == ~0U) {
@@ -850,27 +839,6 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep)
850839
break;
851840
}
852841

853-
/* If using mw bind, start the deregister process now. */
854-
/* (Note: if mr_free(), cannot perform it here, in tasklet context) */
855-
if (req->rl_nchunks) switch (r_xprt->rx_ia.ri_memreg_strategy) {
856-
case RPCRDMA_MEMWINDOWS:
857-
for (i = 0; req->rl_nchunks-- > 1;)
858-
i += rpcrdma_deregister_external(
859-
&req->rl_segments[i], r_xprt, NULL);
860-
/* Optionally wait (not here) for unbinds to complete */
861-
rep->rr_func = rpcrdma_unbind_func;
862-
(void) rpcrdma_deregister_external(&req->rl_segments[i],
863-
r_xprt, rep);
864-
break;
865-
case RPCRDMA_MEMWINDOWS_ASYNC:
866-
for (i = 0; req->rl_nchunks--;)
867-
i += rpcrdma_deregister_external(&req->rl_segments[i],
868-
r_xprt, NULL);
869-
break;
870-
default:
871-
break;
872-
}
873-
874842
dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n",
875843
__func__, xprt, rqst, status);
876844
xprt_complete_rqst(rqst->rq_task, status);

net/sunrpc/xprtrdma/transport.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,7 @@ xprt_rdma_free(void *buffer)
566566
__func__, rep, (rep && rep->rr_func) ? " (with waiter)" : "");
567567

568568
/*
569-
* Finish the deregistration. When using mw bind, this was
570-
* begun in rpcrdma_reply_handler(). In all other modes, we
571-
* do it here, in thread context. The process is considered
569+
* Finish the deregistration. The process is considered
572570
* complete when the rr_func vector becomes NULL - this
573571
* was put in place during rpcrdma_reply_handler() - the wait
574572
* call below will not block if the dereg is "done". If
@@ -580,11 +578,6 @@ xprt_rdma_free(void *buffer)
580578
&req->rl_segments[i], r_xprt, NULL);
581579
}
582580

583-
if (rep && wait_event_interruptible(rep->rr_unbind, !rep->rr_func)) {
584-
rep->rr_func = NULL; /* abandon the callback */
585-
req->rl_reply = NULL;
586-
}
587-
588581
if (req->rl_iov.length == 0) { /* see allocate above */
589582
struct rpcrdma_req *oreq = (struct rpcrdma_req *)req->rl_buffer;
590583
oreq->rl_reply = req->rl_reply;

net/sunrpc/xprtrdma/verbs.c

Lines changed: 5 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void rpcrdma_event_process(struct ib_wc *wc)
152152
dprintk("RPC: %s: event rep %p status %X opcode %X length %u\n",
153153
__func__, rep, wc->status, wc->opcode, wc->byte_len);
154154

155-
if (!rep) /* send or bind completion that we don't care about */
155+
if (!rep) /* send completion that we don't care about */
156156
return;
157157

158158
if (IB_WC_SUCCESS != wc->status) {
@@ -197,8 +197,6 @@ void rpcrdma_event_process(struct ib_wc *wc)
197197
}
198198
atomic_set(&rep->rr_buffer->rb_credits, credits);
199199
}
200-
/* fall through */
201-
case IB_WC_BIND_MW:
202200
rpcrdma_schedule_tasklet(rep);
203201
break;
204202
default:
@@ -233,7 +231,7 @@ rpcrdma_cq_poll(struct ib_cq *cq)
233231
/*
234232
* rpcrdma_cq_event_upcall
235233
*
236-
* This upcall handles recv, send, bind and unbind events.
234+
* This upcall handles recv and send events.
237235
* It is reentrant but processes single events in order to maintain
238236
* ordering of receives to keep server credits.
239237
*
@@ -494,16 +492,6 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
494492
}
495493

496494
switch (memreg) {
497-
case RPCRDMA_MEMWINDOWS:
498-
case RPCRDMA_MEMWINDOWS_ASYNC:
499-
if (!(devattr.device_cap_flags & IB_DEVICE_MEM_WINDOW)) {
500-
dprintk("RPC: %s: MEMWINDOWS registration "
501-
"specified but not supported by adapter, "
502-
"using slower RPCRDMA_REGISTER\n",
503-
__func__);
504-
memreg = RPCRDMA_REGISTER;
505-
}
506-
break;
507495
case RPCRDMA_MTHCAFMR:
508496
if (!ia->ri_id->device->alloc_fmr) {
509497
#if RPCRDMA_PERSISTENT_REGISTRATION
@@ -567,16 +555,13 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
567555
IB_ACCESS_REMOTE_READ;
568556
goto register_setup;
569557
#endif
570-
case RPCRDMA_MEMWINDOWS_ASYNC:
571-
case RPCRDMA_MEMWINDOWS:
572-
mem_priv = IB_ACCESS_LOCAL_WRITE |
573-
IB_ACCESS_MW_BIND;
574-
goto register_setup;
575558
case RPCRDMA_MTHCAFMR:
576559
if (ia->ri_have_dma_lkey)
577560
break;
578561
mem_priv = IB_ACCESS_LOCAL_WRITE;
562+
#if RPCRDMA_PERSISTENT_REGISTRATION
579563
register_setup:
564+
#endif
580565
ia->ri_bind_mem = ib_get_dma_mr(ia->ri_pd, mem_priv);
581566
if (IS_ERR(ia->ri_bind_mem)) {
582567
printk(KERN_ALERT "%s: ib_get_dma_mr for "
@@ -699,14 +684,6 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
699684
}
700685
break;
701686
}
702-
case RPCRDMA_MEMWINDOWS_ASYNC:
703-
case RPCRDMA_MEMWINDOWS:
704-
/* Add room for mw_binds+unbinds - overkill! */
705-
ep->rep_attr.cap.max_send_wr++;
706-
ep->rep_attr.cap.max_send_wr *= (2 * RPCRDMA_MAX_SEGS);
707-
if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
708-
return -EINVAL;
709-
break;
710687
default:
711688
break;
712689
}
@@ -728,26 +705,13 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
728705

729706
/* set trigger for requesting send completion */
730707
ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 /* - 1*/;
731-
switch (ia->ri_memreg_strategy) {
732-
case RPCRDMA_MEMWINDOWS_ASYNC:
733-
case RPCRDMA_MEMWINDOWS:
734-
ep->rep_cqinit -= RPCRDMA_MAX_SEGS;
735-
break;
736-
default:
737-
break;
738-
}
739708
if (ep->rep_cqinit <= 2)
740709
ep->rep_cqinit = 0;
741710
INIT_CQCOUNT(ep);
742711
ep->rep_ia = ia;
743712
init_waitqueue_head(&ep->rep_connect_wait);
744713
INIT_DELAYED_WORK(&ep->rep_connect_worker, rpcrdma_connect_worker);
745714

746-
/*
747-
* Create a single cq for receive dto and mw_bind (only ever
748-
* care about unbind, really). Send completions are suppressed.
749-
* Use single threaded tasklet upcalls to maintain ordering.
750-
*/
751715
ep->rep_cq = ib_create_cq(ia->ri_id->device, rpcrdma_cq_event_upcall,
752716
rpcrdma_cq_async_error_upcall, NULL,
753717
ep->rep_attr.cap.max_recv_wr +
@@ -1020,11 +984,6 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
1020984
len += (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS *
1021985
sizeof(struct rpcrdma_mw);
1022986
break;
1023-
case RPCRDMA_MEMWINDOWS_ASYNC:
1024-
case RPCRDMA_MEMWINDOWS:
1025-
len += (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS *
1026-
sizeof(struct rpcrdma_mw);
1027-
break;
1028987
default:
1029988
break;
1030989
}
@@ -1055,11 +1014,6 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
10551014
}
10561015
p += cdata->padding;
10571016

1058-
/*
1059-
* Allocate the fmr's, or mw's for mw_bind chunk registration.
1060-
* We "cycle" the mw's in order to minimize rkey reuse,
1061-
* and also reduce unbind-to-bind collision.
1062-
*/
10631017
INIT_LIST_HEAD(&buf->rb_mws);
10641018
r = (struct rpcrdma_mw *)p;
10651019
switch (ia->ri_memreg_strategy) {
@@ -1107,21 +1061,6 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
11071061
++r;
11081062
}
11091063
break;
1110-
case RPCRDMA_MEMWINDOWS_ASYNC:
1111-
case RPCRDMA_MEMWINDOWS:
1112-
/* Allocate one extra request's worth, for full cycling */
1113-
for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) {
1114-
r->r.mw = ib_alloc_mw(ia->ri_pd, IB_MW_TYPE_1);
1115-
if (IS_ERR(r->r.mw)) {
1116-
rc = PTR_ERR(r->r.mw);
1117-
dprintk("RPC: %s: ib_alloc_mw"
1118-
" failed %i\n", __func__, rc);
1119-
goto out;
1120-
}
1121-
list_add(&r->mw_list, &buf->rb_mws);
1122-
++r;
1123-
}
1124-
break;
11251064
default:
11261065
break;
11271066
}
@@ -1170,7 +1109,6 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
11701109
memset(rep, 0, sizeof(struct rpcrdma_rep));
11711110
buf->rb_recv_bufs[i] = rep;
11721111
buf->rb_recv_bufs[i]->rr_buffer = buf;
1173-
init_waitqueue_head(&rep->rr_unbind);
11741112

11751113
rc = rpcrdma_register_internal(ia, rep->rr_base,
11761114
len - offsetof(struct rpcrdma_rep, rr_base),
@@ -1204,7 +1142,6 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
12041142

12051143
/* clean up in reverse order from create
12061144
* 1. recv mr memory (mr free, then kfree)
1207-
* 1a. bind mw memory
12081145
* 2. send mr memory (mr free, then kfree)
12091146
* 3. padding (if any) [moved to rpcrdma_ep_destroy]
12101147
* 4. arrays
@@ -1248,15 +1185,6 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
12481185
" failed %i\n",
12491186
__func__, rc);
12501187
break;
1251-
case RPCRDMA_MEMWINDOWS_ASYNC:
1252-
case RPCRDMA_MEMWINDOWS:
1253-
rc = ib_dealloc_mw(r->r.mw);
1254-
if (rc)
1255-
dprintk("RPC: %s:"
1256-
" ib_dealloc_mw"
1257-
" failed %i\n",
1258-
__func__, rc);
1259-
break;
12601188
default:
12611189
break;
12621190
}
@@ -1331,15 +1259,12 @@ rpcrdma_buffer_put(struct rpcrdma_req *req)
13311259
req->rl_niovs = 0;
13321260
if (req->rl_reply) {
13331261
buffers->rb_recv_bufs[--buffers->rb_recv_index] = req->rl_reply;
1334-
init_waitqueue_head(&req->rl_reply->rr_unbind);
13351262
req->rl_reply->rr_func = NULL;
13361263
req->rl_reply = NULL;
13371264
}
13381265
switch (ia->ri_memreg_strategy) {
13391266
case RPCRDMA_FRMR:
13401267
case RPCRDMA_MTHCAFMR:
1341-
case RPCRDMA_MEMWINDOWS_ASYNC:
1342-
case RPCRDMA_MEMWINDOWS:
13431268
/*
13441269
* Cycle mw's back in reverse order, and "spin" them.
13451270
* This delays and scrambles reuse as much as possible.
@@ -1384,8 +1309,7 @@ rpcrdma_recv_buffer_get(struct rpcrdma_req *req)
13841309

13851310
/*
13861311
* Put reply buffers back into pool when not attached to
1387-
* request. This happens in error conditions, and when
1388-
* aborting unbinds. Pre-decrement counter/array index.
1312+
* request. This happens in error conditions.
13891313
*/
13901314
void
13911315
rpcrdma_recv_buffer_put(struct rpcrdma_rep *rep)
@@ -1687,74 +1611,6 @@ rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg,
16871611
return rc;
16881612
}
16891613

1690-
static int
1691-
rpcrdma_register_memwin_external(struct rpcrdma_mr_seg *seg,
1692-
int *nsegs, int writing, struct rpcrdma_ia *ia,
1693-
struct rpcrdma_xprt *r_xprt)
1694-
{
1695-
int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
1696-
IB_ACCESS_REMOTE_READ);
1697-
struct ib_mw_bind param;
1698-
int rc;
1699-
1700-
*nsegs = 1;
1701-
rpcrdma_map_one(ia, seg, writing);
1702-
param.bind_info.mr = ia->ri_bind_mem;
1703-
param.wr_id = 0ULL; /* no send cookie */
1704-
param.bind_info.addr = seg->mr_dma;
1705-
param.bind_info.length = seg->mr_len;
1706-
param.send_flags = 0;
1707-
param.bind_info.mw_access_flags = mem_priv;
1708-
1709-
DECR_CQCOUNT(&r_xprt->rx_ep);
1710-
rc = ib_bind_mw(ia->ri_id->qp, seg->mr_chunk.rl_mw->r.mw, &param);
1711-
if (rc) {
1712-
dprintk("RPC: %s: failed ib_bind_mw "
1713-
"%u@0x%llx status %i\n",
1714-
__func__, seg->mr_len,
1715-
(unsigned long long)seg->mr_dma, rc);
1716-
rpcrdma_unmap_one(ia, seg);
1717-
} else {
1718-
seg->mr_rkey = seg->mr_chunk.rl_mw->r.mw->rkey;
1719-
seg->mr_base = param.bind_info.addr;
1720-
seg->mr_nsegs = 1;
1721-
}
1722-
return rc;
1723-
}
1724-
1725-
static int
1726-
rpcrdma_deregister_memwin_external(struct rpcrdma_mr_seg *seg,
1727-
struct rpcrdma_ia *ia,
1728-
struct rpcrdma_xprt *r_xprt, void **r)
1729-
{
1730-
struct ib_mw_bind param;
1731-
LIST_HEAD(l);
1732-
int rc;
1733-
1734-
BUG_ON(seg->mr_nsegs != 1);
1735-
param.bind_info.mr = ia->ri_bind_mem;
1736-
param.bind_info.addr = 0ULL; /* unbind */
1737-
param.bind_info.length = 0;
1738-
param.bind_info.mw_access_flags = 0;
1739-
if (*r) {
1740-
param.wr_id = (u64) (unsigned long) *r;
1741-
param.send_flags = IB_SEND_SIGNALED;
1742-
INIT_CQCOUNT(&r_xprt->rx_ep);
1743-
} else {
1744-
param.wr_id = 0ULL;
1745-
param.send_flags = 0;
1746-
DECR_CQCOUNT(&r_xprt->rx_ep);
1747-
}
1748-
rc = ib_bind_mw(ia->ri_id->qp, seg->mr_chunk.rl_mw->r.mw, &param);
1749-
rpcrdma_unmap_one(ia, seg);
1750-
if (rc)
1751-
dprintk("RPC: %s: failed ib_(un)bind_mw,"
1752-
" status %i\n", __func__, rc);
1753-
else
1754-
*r = NULL; /* will upcall on completion */
1755-
return rc;
1756-
}
1757-
17581614
static int
17591615
rpcrdma_register_default_external(struct rpcrdma_mr_seg *seg,
17601616
int *nsegs, int writing, struct rpcrdma_ia *ia)
@@ -1845,12 +1701,6 @@ rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
18451701
rc = rpcrdma_register_fmr_external(seg, &nsegs, writing, ia);
18461702
break;
18471703

1848-
/* Registration using memory windows */
1849-
case RPCRDMA_MEMWINDOWS_ASYNC:
1850-
case RPCRDMA_MEMWINDOWS:
1851-
rc = rpcrdma_register_memwin_external(seg, &nsegs, writing, ia, r_xprt);
1852-
break;
1853-
18541704
/* Default registration each time */
18551705
default:
18561706
rc = rpcrdma_register_default_external(seg, &nsegs, writing, ia);
@@ -1887,11 +1737,6 @@ rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
18871737
rc = rpcrdma_deregister_fmr_external(seg, ia);
18881738
break;
18891739

1890-
case RPCRDMA_MEMWINDOWS_ASYNC:
1891-
case RPCRDMA_MEMWINDOWS:
1892-
rc = rpcrdma_deregister_memwin_external(seg, ia, r_xprt, &r);
1893-
break;
1894-
18951740
default:
18961741
rc = rpcrdma_deregister_default_external(seg, ia);
18971742
break;

0 commit comments

Comments
 (0)