diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2015-03-30 14:34:58 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2015-03-31 09:52:52 -0400 |
commit | 91e70e70e47b3355bb0a8b3b196c93897dcdb440 (patch) | |
tree | 64cc0c734337a26487fb1960bd9e950a1d8afc19 | |
parent | 6814baead86b5d44096ddfbb6f944163578e68c3 (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.c | 42 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/frwr_ops.c | 66 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/physical_ops.c | 7 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 104 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 1 |
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 | ||
32 | static int | ||
33 | fmr_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 | |||
66 | out_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 | ||
20 | static 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 | |||
35 | out_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 | |||
41 | out_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 | ||
61 | static int | ||
62 | frwr_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 | ||
31 | static int | ||
32 | physical_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 | ||
1127 | static int | ||
1128 | rpcrdma_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 | |||
1160 | out_free: | ||
1161 | kfree(r); | ||
1162 | return rc; | ||
1163 | } | ||
1164 | |||
1165 | static int | ||
1166 | rpcrdma_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 | |||
1207 | out_free: | ||
1208 | kfree(r); | ||
1209 | return rc; | ||
1210 | } | ||
1211 | |||
1212 | int | 1127 | int |
1213 | rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) | 1128 | rpcrdma_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 | ||