aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2015-03-30 14:34:58 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2015-03-31 09:52:52 -0400
commit91e70e70e47b3355bb0a8b3b196c93897dcdb440 (patch)
tree64cc0c734337a26487fb1960bd9e950a1d8afc19
parent6814baead86b5d44096ddfbb6f944163578e68c3 (diff)
xprtrdma: Add "init MRs" memreg op
This method is used when setting up a new transport instance to create a pool of Memory Region objects that will be used to register memory during operation. Memory Regions are not needed for "physical" registration, since ->prepare and ->release are no-ops for that mode. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Sagi Grimberg <sagig@mellanox.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.c42
-rw-r--r--net/sunrpc/xprtrdma/frwr_ops.c66
-rw-r--r--net/sunrpc/xprtrdma/physical_ops.c7
-rw-r--r--net/sunrpc/xprtrdma/verbs.c104
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h1
5 files changed, 119 insertions, 101 deletions
diff --git a/net/sunrpc/xprtrdma/fmr_ops.c b/net/sunrpc/xprtrdma/fmr_ops.c
index 888aa107cf0b..825ce9641350 100644
--- a/net/sunrpc/xprtrdma/fmr_ops.c
+++ b/net/sunrpc/xprtrdma/fmr_ops.c
@@ -29,6 +29,47 @@ fmr_op_maxpages(struct rpcrdma_xprt *r_xprt)
29 rpcrdma_max_segments(r_xprt) * RPCRDMA_MAX_FMR_SGES); 29 rpcrdma_max_segments(r_xprt) * RPCRDMA_MAX_FMR_SGES);
30} 30}
31 31
32static int
33fmr_op_init(struct rpcrdma_xprt *r_xprt)
34{
35 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
36 int mr_access_flags = IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ;
37 struct ib_fmr_attr fmr_attr = {
38 .max_pages = RPCRDMA_MAX_FMR_SGES,
39 .max_maps = 1,
40 .page_shift = PAGE_SHIFT
41 };
42 struct ib_pd *pd = r_xprt->rx_ia.ri_pd;
43 struct rpcrdma_mw *r;
44 int i, rc;
45
46 INIT_LIST_HEAD(&buf->rb_mws);
47 INIT_LIST_HEAD(&buf->rb_all);
48
49 i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS;
50 dprintk("RPC: %s: initalizing %d FMRs\n", __func__, i);
51
52 while (i--) {
53 r = kzalloc(sizeof(*r), GFP_KERNEL);
54 if (!r)
55 return -ENOMEM;
56
57 r->r.fmr = ib_alloc_fmr(pd, mr_access_flags, &fmr_attr);
58 if (IS_ERR(r->r.fmr))
59 goto out_fmr_err;
60
61 list_add(&r->mw_list, &buf->rb_mws);
62 list_add(&r->mw_all, &buf->rb_all);
63 }
64 return 0;
65
66out_fmr_err:
67 rc = PTR_ERR(r->r.fmr);
68 dprintk("RPC: %s: ib_alloc_fmr status %i\n", __func__, rc);
69 kfree(r);
70 return rc;
71}
72
32/* Use the ib_map_phys_fmr() verb to register a memory region 73/* Use the ib_map_phys_fmr() verb to register a memory region
33 * for remote access via RDMA READ or RDMA WRITE. 74 * for remote access via RDMA READ or RDMA WRITE.
34 */ 75 */
@@ -109,5 +150,6 @@ const struct rpcrdma_memreg_ops rpcrdma_fmr_memreg_ops = {
109 .ro_map = fmr_op_map, 150 .ro_map = fmr_op_map,
110 .ro_unmap = fmr_op_unmap, 151 .ro_unmap = fmr_op_unmap,
111 .ro_maxpages = fmr_op_maxpages, 152 .ro_maxpages = fmr_op_maxpages,
153 .ro_init = fmr_op_init,
112 .ro_displayname = "fmr", 154 .ro_displayname = "fmr",
113}; 155};
diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
index 35b725bf0afb..9168c15faafa 100644
--- a/net/sunrpc/xprtrdma/frwr_ops.c
+++ b/net/sunrpc/xprtrdma/frwr_ops.c
@@ -17,6 +17,35 @@
17# define RPCDBG_FACILITY RPCDBG_TRANS 17# define RPCDBG_FACILITY RPCDBG_TRANS
18#endif 18#endif
19 19
20static int
21__frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, struct ib_device *device,
22 unsigned int depth)
23{
24 struct rpcrdma_frmr *f = &r->r.frmr;
25 int rc;
26
27 f->fr_mr = ib_alloc_fast_reg_mr(pd, depth);
28 if (IS_ERR(f->fr_mr))
29 goto out_mr_err;
30 f->fr_pgl = ib_alloc_fast_reg_page_list(device, depth);
31 if (IS_ERR(f->fr_pgl))
32 goto out_list_err;
33 return 0;
34
35out_mr_err:
36 rc = PTR_ERR(f->fr_mr);
37 dprintk("RPC: %s: ib_alloc_fast_reg_mr status %i\n",
38 __func__, rc);
39 return rc;
40
41out_list_err:
42 rc = PTR_ERR(f->fr_pgl);
43 dprintk("RPC: %s: ib_alloc_fast_reg_page_list status %i\n",
44 __func__, rc);
45 ib_dereg_mr(f->fr_mr);
46 return rc;
47}
48
20/* FRWR mode conveys a list of pages per chunk segment. The 49/* FRWR mode conveys a list of pages per chunk segment. The
21 * maximum length of that list is the FRWR page list depth. 50 * maximum length of that list is the FRWR page list depth.
22 */ 51 */
@@ -29,6 +58,42 @@ frwr_op_maxpages(struct rpcrdma_xprt *r_xprt)
29 rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth); 58 rpcrdma_max_segments(r_xprt) * ia->ri_max_frmr_depth);
30} 59}
31 60
61static int
62frwr_op_init(struct rpcrdma_xprt *r_xprt)
63{
64 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
65 struct ib_device *device = r_xprt->rx_ia.ri_id->device;
66 unsigned int depth = r_xprt->rx_ia.ri_max_frmr_depth;
67 struct ib_pd *pd = r_xprt->rx_ia.ri_pd;
68 int i;
69
70 INIT_LIST_HEAD(&buf->rb_mws);
71 INIT_LIST_HEAD(&buf->rb_all);
72
73 i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS;
74 dprintk("RPC: %s: initalizing %d FRMRs\n", __func__, i);
75
76 while (i--) {
77 struct rpcrdma_mw *r;
78 int rc;
79
80 r = kzalloc(sizeof(*r), GFP_KERNEL);
81 if (!r)
82 return -ENOMEM;
83
84 rc = __frwr_init(r, pd, device, depth);
85 if (rc) {
86 kfree(r);
87 return rc;
88 }
89
90 list_add(&r->mw_list, &buf->rb_mws);
91 list_add(&r->mw_all, &buf->rb_all);
92 }
93
94 return 0;
95}
96
32/* Post a FAST_REG Work Request to register a memory region 97/* Post a FAST_REG Work Request to register a memory region
33 * for remote access via RDMA READ or RDMA WRITE. 98 * for remote access via RDMA READ or RDMA WRITE.
34 */ 99 */
@@ -149,5 +214,6 @@ const struct rpcrdma_memreg_ops rpcrdma_frwr_memreg_ops = {
149 .ro_map = frwr_op_map, 214 .ro_map = frwr_op_map,
150 .ro_unmap = frwr_op_unmap, 215 .ro_unmap = frwr_op_unmap,
151 .ro_maxpages = frwr_op_maxpages, 216 .ro_maxpages = frwr_op_maxpages,
217 .ro_init = frwr_op_init,
152 .ro_displayname = "frwr", 218 .ro_displayname = "frwr",
153}; 219};
diff --git a/net/sunrpc/xprtrdma/physical_ops.c b/net/sunrpc/xprtrdma/physical_ops.c
index 5b5a63adfdf3..c37205190a2f 100644
--- a/net/sunrpc/xprtrdma/physical_ops.c
+++ b/net/sunrpc/xprtrdma/physical_ops.c
@@ -28,6 +28,12 @@ physical_op_maxpages(struct rpcrdma_xprt *r_xprt)
28 rpcrdma_max_segments(r_xprt)); 28 rpcrdma_max_segments(r_xprt));
29} 29}
30 30
31static int
32physical_op_init(struct rpcrdma_xprt *r_xprt)
33{
34 return 0;
35}
36
31/* The client's physical memory is already exposed for 37/* The client's physical memory is already exposed for
32 * remote access via RDMA READ or RDMA WRITE. 38 * remote access via RDMA READ or RDMA WRITE.
33 */ 39 */
@@ -57,5 +63,6 @@ const struct rpcrdma_memreg_ops rpcrdma_physical_memreg_ops = {
57 .ro_map = physical_op_map, 63 .ro_map = physical_op_map,
58 .ro_unmap = physical_op_unmap, 64 .ro_unmap = physical_op_unmap,
59 .ro_maxpages = physical_op_maxpages, 65 .ro_maxpages = physical_op_maxpages,
66 .ro_init = physical_op_init,
60 .ro_displayname = "physical", 67 .ro_displayname = "physical",
61}; 68};
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index b167c99fbfb6..e89a57d4e4f2 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -1124,91 +1124,6 @@ out:
1124 return ERR_PTR(rc); 1124 return ERR_PTR(rc);
1125} 1125}
1126 1126
1127static int
1128rpcrdma_init_fmrs(struct rpcrdma_ia *ia, struct rpcrdma_buffer *buf)
1129{
1130 int mr_access_flags = IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ;
1131 struct ib_fmr_attr fmr_attr = {
1132 .max_pages = RPCRDMA_MAX_DATA_SEGS,
1133 .max_maps = 1,
1134 .page_shift = PAGE_SHIFT
1135 };
1136 struct rpcrdma_mw *r;
1137 int i, rc;
1138
1139 i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS;
1140 dprintk("RPC: %s: initalizing %d FMRs\n", __func__, i);
1141
1142 while (i--) {
1143 r = kzalloc(sizeof(*r), GFP_KERNEL);
1144 if (r == NULL)
1145 return -ENOMEM;
1146
1147 r->r.fmr = ib_alloc_fmr(ia->ri_pd, mr_access_flags, &fmr_attr);
1148 if (IS_ERR(r->r.fmr)) {
1149 rc = PTR_ERR(r->r.fmr);
1150 dprintk("RPC: %s: ib_alloc_fmr failed %i\n",
1151 __func__, rc);
1152 goto out_free;
1153 }
1154
1155 list_add(&r->mw_list, &buf->rb_mws);
1156 list_add(&r->mw_all, &buf->rb_all);
1157 }
1158 return 0;
1159
1160out_free:
1161 kfree(r);
1162 return rc;
1163}
1164
1165static int
1166rpcrdma_init_frmrs(struct rpcrdma_ia *ia, struct rpcrdma_buffer *buf)
1167{
1168 struct rpcrdma_frmr *f;
1169 struct rpcrdma_mw *r;
1170 int i, rc;
1171
1172 i = (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS;
1173 dprintk("RPC: %s: initalizing %d FRMRs\n", __func__, i);
1174
1175 while (i--) {
1176 r = kzalloc(sizeof(*r), GFP_KERNEL);
1177 if (r == NULL)
1178 return -ENOMEM;
1179 f = &r->r.frmr;
1180
1181 f->fr_mr = ib_alloc_fast_reg_mr(ia->ri_pd,
1182 ia->ri_max_frmr_depth);
1183 if (IS_ERR(f->fr_mr)) {
1184 rc = PTR_ERR(f->fr_mr);
1185 dprintk("RPC: %s: ib_alloc_fast_reg_mr "
1186 "failed %i\n", __func__, rc);
1187 goto out_free;
1188 }
1189
1190 f->fr_pgl = ib_alloc_fast_reg_page_list(ia->ri_id->device,
1191 ia->ri_max_frmr_depth);
1192 if (IS_ERR(f->fr_pgl)) {
1193 rc = PTR_ERR(f->fr_pgl);
1194 dprintk("RPC: %s: ib_alloc_fast_reg_page_list "
1195 "failed %i\n", __func__, rc);
1196
1197 ib_dereg_mr(f->fr_mr);
1198 goto out_free;
1199 }
1200
1201 list_add(&r->mw_list, &buf->rb_mws);
1202 list_add(&r->mw_all, &buf->rb_all);
1203 }
1204
1205 return 0;
1206
1207out_free:
1208 kfree(r);
1209 return rc;
1210}
1211
1212int 1127int
1213rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) 1128rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
1214{ 1129{
@@ -1245,22 +1160,9 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
1245 buf->rb_recv_bufs = (struct rpcrdma_rep **) p; 1160 buf->rb_recv_bufs = (struct rpcrdma_rep **) p;
1246 p = (char *) &buf->rb_recv_bufs[buf->rb_max_requests]; 1161 p = (char *) &buf->rb_recv_bufs[buf->rb_max_requests];
1247 1162
1248 INIT_LIST_HEAD(&buf->rb_mws); 1163 rc = ia->ri_ops->ro_init(r_xprt);
1249 INIT_LIST_HEAD(&buf->rb_all); 1164 if (rc)
1250 switch (ia->ri_memreg_strategy) { 1165 goto out;
1251 case RPCRDMA_FRMR:
1252 rc = rpcrdma_init_frmrs(ia, buf);
1253 if (rc)
1254 goto out;
1255 break;
1256 case RPCRDMA_MTHCAFMR:
1257 rc = rpcrdma_init_fmrs(ia, buf);
1258 if (rc)
1259 goto out;
1260 break;
1261 default:
1262 break;
1263 }
1264 1166
1265 for (i = 0; i < buf->rb_max_requests; i++) { 1167 for (i = 0; i < buf->rb_max_requests; i++) {
1266 struct rpcrdma_req *req; 1168 struct rpcrdma_req *req;
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 9a727f960df9..90b60feab45a 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -341,6 +341,7 @@ struct rpcrdma_memreg_ops {
341 int (*ro_unmap)(struct rpcrdma_xprt *, 341 int (*ro_unmap)(struct rpcrdma_xprt *,
342 struct rpcrdma_mr_seg *); 342 struct rpcrdma_mr_seg *);
343 size_t (*ro_maxpages)(struct rpcrdma_xprt *); 343 size_t (*ro_maxpages)(struct rpcrdma_xprt *);
344 int (*ro_init)(struct rpcrdma_xprt *);
344 const char *ro_displayname; 345 const char *ro_displayname;
345}; 346};
346 347