Skip to content

Commit 6814bae

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Add a "deregister_external" op for each memreg mode
There is very little common processing among the different external memory deregistration functions. Signed-off-by: Chuck Lever <[email protected]> Tested-by: Devesh Sharma <[email protected]> Tested-by: Meghana Cheripady <[email protected]> Tested-by: Veeresh U. Kokatnur <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 9c1b4d7 commit 6814bae

File tree

7 files changed

+84
-90
lines changed

7 files changed

+84
-90
lines changed

net/sunrpc/xprtrdma/fmr_ops.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,35 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
7979
return rc;
8080
}
8181

82+
/* Use the ib_unmap_fmr() verb to prevent further remote
83+
* access via RDMA READ or RDMA WRITE.
84+
*/
85+
static int
86+
fmr_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg)
87+
{
88+
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
89+
struct rpcrdma_mr_seg *seg1 = seg;
90+
int rc, nsegs = seg->mr_nsegs;
91+
LIST_HEAD(l);
92+
93+
list_add(&seg1->rl_mw->r.fmr->list, &l);
94+
rc = ib_unmap_fmr(&l);
95+
read_lock(&ia->ri_qplock);
96+
while (seg1->mr_nsegs--)
97+
rpcrdma_unmap_one(ia, seg++);
98+
read_unlock(&ia->ri_qplock);
99+
if (rc)
100+
goto out_err;
101+
return nsegs;
102+
103+
out_err:
104+
dprintk("RPC: %s: ib_unmap_fmr status %i\n", __func__, rc);
105+
return nsegs;
106+
}
107+
82108
const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
83109
.ro_map = fmr_op_map,
110+
.ro_unmap = fmr_op_unmap,
84111
.ro_maxpages = fmr_op_maxpages,
85112
.ro_displayname = "fmr",
86113
};

net/sunrpc/xprtrdma/frwr_ops.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,44 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
110110
return rc;
111111
}
112112

113+
/* Post a LOCAL_INV Work Request to prevent further remote access
114+
* via RDMA READ or RDMA WRITE.
115+
*/
116+
static int
117+
frwr_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg)
118+
{
119+
struct rpcrdma_mr_seg *seg1 = seg;
120+
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
121+
struct ib_send_wr invalidate_wr, *bad_wr;
122+
int rc, nsegs = seg->mr_nsegs;
123+
124+
seg1->rl_mw->r.frmr.fr_state = FRMR_IS_INVALID;
125+
126+
memset(&invalidate_wr, 0, sizeof(invalidate_wr));
127+
invalidate_wr.wr_id = (unsigned long)(void *)seg1->rl_mw;
128+
invalidate_wr.opcode = IB_WR_LOCAL_INV;
129+
invalidate_wr.ex.invalidate_rkey = seg1->rl_mw->r.frmr.fr_mr->rkey;
130+
DECR_CQCOUNT(&r_xprt->rx_ep);
131+
132+
read_lock(&ia->ri_qplock);
133+
while (seg1->mr_nsegs--)
134+
rpcrdma_unmap_one(ia, seg++);
135+
rc = ib_post_send(ia->ri_id->qp, &invalidate_wr, &bad_wr);
136+
read_unlock(&ia->ri_qplock);
137+
if (rc)
138+
goto out_err;
139+
return nsegs;
140+
141+
out_err:
142+
/* Force rpcrdma_buffer_get() to retry */
143+
seg1->rl_mw->r.frmr.fr_state = FRMR_IS_STALE;
144+
dprintk("RPC: %s: ib_post_send status %i\n", __func__, rc);
145+
return nsegs;
146+
}
147+
113148
const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
114149
.ro_map = frwr_op_map,
150+
.ro_unmap = frwr_op_unmap,
115151
.ro_maxpages = frwr_op_maxpages,
116152
.ro_displayname = "frwr",
117153
};

net/sunrpc/xprtrdma/physical_ops.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,18 @@ physical_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
4444
return 1;
4545
}
4646

47+
/* Unmap a memory region, but leave it registered.
48+
*/
49+
static int
50+
physical_op_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg)
51+
{
52+
rpcrdma_unmap_one(&r_xprt->rx_ia, seg);
53+
return 1;
54+
}
55+
4756
const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = {
4857
.ro_map = physical_op_map,
58+
.ro_unmap = physical_op_unmap,
4959
.ro_maxpages = physical_op_maxpages,
5060
.ro_displayname = "physical",
5161
};

net/sunrpc/xprtrdma/rpc_rdma.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,12 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
284284
return (unsigned char *)iptr - (unsigned char *)headerp;
285285

286286
out:
287-
if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_FRMR) {
288-
for (pos = 0; nchunks--;)
289-
pos += rpcrdma_deregister_external(
290-
&req->rl_segments[pos], r_xprt);
291-
}
287+
if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
288+
return n;
289+
290+
for (pos = 0; nchunks--;)
291+
pos += r_xprt->rx_ia.ri_ops->ro_unmap(r_xprt,
292+
&req->rl_segments[pos]);
292293
return n;
293294
}
294295

net/sunrpc/xprtrdma/transport.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,8 +584,8 @@ xprt_rdma_free(void *buffer)
584584

585585
for (i = 0; req->rl_nchunks;) {
586586
--req->rl_nchunks;
587-
i += rpcrdma_deregister_external(
588-
&req->rl_segments[i], r_xprt);
587+
i += r_xprt->rx_ia.ri_ops->ro_unmap(r_xprt,
588+
&req->rl_segments[i]);
589589
}
590590

591591
rpcrdma_buffer_put(req);

net/sunrpc/xprtrdma/verbs.c

Lines changed: 1 addition & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ rpcrdma_buffer_put_sendbuf(struct rpcrdma_req *req, struct rpcrdma_buffer *buf)
15101510
}
15111511
}
15121512

1513-
/* rpcrdma_unmap_one() was already done by rpcrdma_deregister_frmr_external().
1513+
/* rpcrdma_unmap_one() was already done during deregistration.
15141514
* Redo only the ib_post_send().
15151515
*/
15161516
static void
@@ -1890,85 +1890,6 @@ rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg)
18901890
seg->mr_dma, seg->mr_dmalen, seg->mr_dir);
18911891
}
18921892

1893-
static int
1894-
rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg,
1895-
struct rpcrdma_ia *ia, struct rpcrdma_xprt *r_xprt)
1896-
{
1897-
struct rpcrdma_mr_seg *seg1 = seg;
1898-
struct ib_send_wr invalidate_wr, *bad_wr;
1899-
int rc;
1900-
1901-
seg1->rl_mw->r.frmr.fr_state = FRMR_IS_INVALID;
1902-
1903-
memset(&invalidate_wr, 0, sizeof invalidate_wr);
1904-
invalidate_wr.wr_id = (unsigned long)(void *)seg1->rl_mw;
1905-
invalidate_wr.opcode = IB_WR_LOCAL_INV;
1906-
invalidate_wr.ex.invalidate_rkey = seg1->rl_mw->r.frmr.fr_mr->rkey;
1907-
DECR_CQCOUNT(&r_xprt->rx_ep);
1908-
1909-
read_lock(&ia->ri_qplock);
1910-
while (seg1->mr_nsegs--)
1911-
rpcrdma_unmap_one(ia, seg++);
1912-
rc = ib_post_send(ia->ri_id->qp, &invalidate_wr, &bad_wr);
1913-
read_unlock(&ia->ri_qplock);
1914-
if (rc) {
1915-
/* Force rpcrdma_buffer_get() to retry */
1916-
seg1->rl_mw->r.frmr.fr_state = FRMR_IS_STALE;
1917-
dprintk("RPC: %s: failed ib_post_send for invalidate,"
1918-
" status %i\n", __func__, rc);
1919-
}
1920-
return rc;
1921-
}
1922-
1923-
static int
1924-
rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg,
1925-
struct rpcrdma_ia *ia)
1926-
{
1927-
struct rpcrdma_mr_seg *seg1 = seg;
1928-
LIST_HEAD(l);
1929-
int rc;
1930-
1931-
list_add(&seg1->rl_mw->r.fmr->list, &l);
1932-
rc = ib_unmap_fmr(&l);
1933-
read_lock(&ia->ri_qplock);
1934-
while (seg1->mr_nsegs--)
1935-
rpcrdma_unmap_one(ia, seg++);
1936-
read_unlock(&ia->ri_qplock);
1937-
if (rc)
1938-
dprintk("RPC: %s: failed ib_unmap_fmr,"
1939-
" status %i\n", __func__, rc);
1940-
return rc;
1941-
}
1942-
1943-
int
1944-
rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
1945-
struct rpcrdma_xprt *r_xprt)
1946-
{
1947-
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
1948-
int nsegs = seg->mr_nsegs, rc;
1949-
1950-
switch (ia->ri_memreg_strategy) {
1951-
1952-
case RPCRDMA_ALLPHYSICAL:
1953-
read_lock(&ia->ri_qplock);
1954-
rpcrdma_unmap_one(ia, seg);
1955-
read_unlock(&ia->ri_qplock);
1956-
break;
1957-
1958-
case RPCRDMA_FRMR:
1959-
rc = rpcrdma_deregister_frmr_external(seg, ia, r_xprt);
1960-
break;
1961-
1962-
case RPCRDMA_MTHCAFMR:
1963-
rc = rpcrdma_deregister_fmr_external(seg, ia);
1964-
break;
1965-
1966-
default:
1967-
break;
1968-
}
1969-
return nsegs;
1970-
}
1971-
19721893
/*
19731894
* Prepost any receive buffer, then post send.
19741895
*

net/sunrpc/xprtrdma/xprt_rdma.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ struct rpcrdma_xprt;
338338
struct rpcrdma_memreg_ops {
339339
int (*ro_map)(struct rpcrdma_xprt *,
340340
struct rpcrdma_mr_seg *, int, bool);
341+
int (*ro_unmap)(struct rpcrdma_xprt *,
342+
struct rpcrdma_mr_seg *);
341343
size_t (*ro_maxpages)(struct rpcrdma_xprt *);
342344
const char *ro_displayname;
343345
};
@@ -405,9 +407,6 @@ void rpcrdma_buffer_put(struct rpcrdma_req *);
405407
void rpcrdma_recv_buffer_get(struct rpcrdma_req *);
406408
void rpcrdma_recv_buffer_put(struct rpcrdma_rep *);
407409

408-
int rpcrdma_deregister_external(struct rpcrdma_mr_seg *,
409-
struct rpcrdma_xprt *);
410-
411410
struct rpcrdma_regbuf *rpcrdma_alloc_regbuf(struct rpcrdma_ia *,
412411
size_t, gfp_t);
413412
void rpcrdma_free_regbuf(struct rpcrdma_ia *,

0 commit comments

Comments
 (0)