aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2015-03-30 14:34:48 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2015-03-31 09:52:52 -0400
commit6814baead86b5d44096ddfbb6f944163578e68c3 (patch)
tree56dbce03517cd92027741bcdf6ca24fb929700c0
parent9c1b4d775f2d7dd5bb806e3de2f3e1244a7cbd16 (diff)
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 <chuck.lever@oracle.com> Tested-by: Devesh Sharma <Devesh.Sharma@Emulex.Com> Tested-by: Meghana Cheripady <Meghana.Cheripady@Emulex.Com> Tested-by: Veeresh U. Kokatnur <veereshuk@chelsio.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--net/sunrpc/xprtrdma/fmr_ops.c27
-rw-r--r--net/sunrpc/xprtrdma/frwr_ops.c36
-rw-r--r--net/sunrpc/xprtrdma/physical_ops.c10
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c11
-rw-r--r--net/sunrpc/xprtrdma/transport.c4
-rw-r--r--net/sunrpc/xprtrdma/verbs.c81
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h5
7 files changed, 84 insertions, 90 deletions
diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c
index 45fb646a6d36..888aa107cf0b 100644
--- a/net/sunrpc/xprtrdma/fmr_ops.c
+++ b/net/sunrpc/xprtrdma/fmr_ops.c
@@ -79,8 +79,35 @@ out_maperr:
79 return rc; 79 return rc;
80} 80}
81 81
82/* Use the ib_unmap_fmr() verb to prevent further remote
83 * access via RDMA READ or RDMA WRITE.
84 */
85static int
86fmr_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
103out_err:
104 dprintk("RPC: %s: ib_unmap_fmr status %i\n", __func__, rc);
105 return nsegs;
106}
107
82const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = { 108const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
83 .ro_map = fmr_op_map, 109 .ro_map = fmr_op_map,
110 .ro_unmap = fmr_op_unmap,
84 .ro_maxpages = fmr_op_maxpages, 111 .ro_maxpages = fmr_op_maxpages,
85 .ro_displayname = "fmr", 112 .ro_displayname = "fmr",
86}; 113};
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
index 23e4d99a2097..35b725bf0afb 100644
--- a/net/sunrpc/xprtrdma/frwr_ops.c
+++ b/net/sunrpc/xprtrdma/frwr_ops.c
@@ -110,8 +110,44 @@ out_senderr:
110 return rc; 110 return rc;
111} 111}
112 112
113/* Post a LOCAL_INV Work Request to prevent further remote access
114 * via RDMA READ or RDMA WRITE.
115 */
116static int
117frwr_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
141out_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
113const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = { 148const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
114 .ro_map = frwr_op_map, 149 .ro_map = frwr_op_map,
150 .ro_unmap = frwr_op_unmap,
115 .ro_maxpages = frwr_op_maxpages, 151 .ro_maxpages = frwr_op_maxpages,
116 .ro_displayname = "frwr", 152 .ro_displayname = "frwr",
117}; 153};
diff --git a/net/sunrpc/xprtrdma/physical_ops.c b/net/sunrpc/xprtrdma/physical_ops.c
index 5a284ee0e058..5b5a63adfdf3 100644
--- a/net/sunrpc/xprtrdma/physical_ops.c
+++ b/net/sunrpc/xprtrdma/physical_ops.c
@@ -44,8 +44,18 @@ physical_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg,
44 return 1; 44 return 1;
45} 45}
46 46
47/* Unmap a memory region, but leave it registered.
48 */
49static int
50physical_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
47const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = { 56const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = {
48 .ro_map = physical_op_map, 57 .ro_map = physical_op_map,
58 .ro_unmap = physical_op_unmap,
49 .ro_maxpages = physical_op_maxpages, 59 .ro_maxpages = physical_op_maxpages,
50 .ro_displayname = "physical", 60 .ro_displayname = "physical",
51}; 61};
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 6ab1d03d7f3e..2c53ea9e1b83 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -284,11 +284,12 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
284 return (unsigned char *)iptr - (unsigned char *)headerp; 284 return (unsigned char *)iptr - (unsigned char *)headerp;
285 285
286out: 286out:
287 if (r_xprt->rx_ia.ri_memreg_strategy != RPCRDMA_FRMR) { 287 if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_FRMR)
288 for (pos = 0; nchunks--;) 288 return n;
289 pos += rpcrdma_deregister_external( 289
290 &req->rl_segments[pos], r_xprt); 290 for (pos = 0; nchunks--;)
291 } 291 pos += r_xprt->rx_ia.ri_ops->ro_unmap(r_xprt,
292 &req->rl_segments[pos]);
292 return n; 293 return n;
293} 294}
294 295
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index da71a24641e3..54f23b1be986 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -584,8 +584,8 @@ xprt_rdma_free(void *buffer)
584 584
585 for (i = 0; req->rl_nchunks;) { 585 for (i = 0; req->rl_nchunks;) {
586 --req->rl_nchunks; 586 --req->rl_nchunks;
587 i += rpcrdma_deregister_external( 587 i += r_xprt->rx_ia.ri_ops->ro_unmap(r_xprt,
588 &req->rl_segments[i], r_xprt); 588 &req->rl_segments[i]);
589 } 589 }
590 590
591 rpcrdma_buffer_put(req); 591 rpcrdma_buffer_put(req);
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 4318c04e095c..b167c99fbfb6 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -1510,7 +1510,7 @@ rpcrdma_buffer_put_sendbuf(struct rpcrdma_req *req, struct rpcrdma_buffer *buf)
1510 } 1510 }
1511} 1511}
1512 1512
1513/* rpcrdma_unmap_one() was already done by rpcrdma_deregister_frmr_external(). 1513/* rpcrdma_unmap_one() was already done during deregistration.
1514 * Redo only the ib_post_send(). 1514 * Redo only the ib_post_send().
1515 */ 1515 */
1516static void 1516static void
@@ -1890,85 +1890,6 @@ rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg)
1890 seg->mr_dma, seg->mr_dmalen, seg->mr_dir); 1890 seg->mr_dma, seg->mr_dmalen, seg->mr_dir);
1891} 1891}
1892 1892
1893static int
1894rpcrdma_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
1923static int
1924rpcrdma_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
1943int
1944rpcrdma_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
1972/* 1893/*
1973 * Prepost any receive buffer, then post send. 1894 * Prepost any receive buffer, then post send.
1974 * 1895 *
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 7bf077bf751d..9a727f960df9 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -338,6 +338,8 @@ struct rpcrdma_xprt;
338struct rpcrdma_memreg_ops { 338struct rpcrdma_memreg_ops {
339 int (*ro_map)(struct rpcrdma_xprt *, 339 int (*ro_map)(struct rpcrdma_xprt *,
340 struct rpcrdma_mr_seg *, int, bool); 340 struct rpcrdma_mr_seg *, int, bool);
341 int (*ro_unmap)(struct rpcrdma_xprt *,
342 struct rpcrdma_mr_seg *);
341 size_t (*ro_maxpages)(struct rpcrdma_xprt *); 343 size_t (*ro_maxpages)(struct rpcrdma_xprt *);
342 const char *ro_displayname; 344 const char *ro_displayname;
343}; 345};
@@ -405,9 +407,6 @@ void rpcrdma_buffer_put(struct rpcrdma_req *);
405void rpcrdma_recv_buffer_get(struct rpcrdma_req *); 407void rpcrdma_recv_buffer_get(struct rpcrdma_req *);
406void rpcrdma_recv_buffer_put(struct rpcrdma_rep *); 408void rpcrdma_recv_buffer_put(struct rpcrdma_rep *);
407 409
408int rpcrdma_deregister_external(struct rpcrdma_mr_seg *,
409 struct rpcrdma_xprt *);
410
411struct rpcrdma_regbuf *rpcrdma_alloc_regbuf(struct rpcrdma_ia *, 410struct rpcrdma_regbuf *rpcrdma_alloc_regbuf(struct rpcrdma_ia *,
412 size_t, gfp_t); 411 size_t, gfp_t);
413void rpcrdma_free_regbuf(struct rpcrdma_ia *, 412void rpcrdma_free_regbuf(struct rpcrdma_ia *,