diff options
| -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 | ||
