diff options
author | Alex Tabachnik <alext@mellanox.com> | 2014-03-05 12:43:47 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-03-18 01:33:58 -0400 |
commit | 6b5a8fb0d22f95fff1eefe1545aa2c7771cacc3f (patch) | |
tree | 0ac6a2d05f977960f3eeae0d06c9f044045b9fdd | |
parent | 7f73384752af3caf0756cf807b2f7fbac50982d1 (diff) |
IB/iser: Initialize T10-PI resources
During connection establishment we also initialize T10-PI resources
(QP, PI contexts) in order to support SCSI's protection operations.
Signed-off-by: Alex Tabachnik <alext@mellanox.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 21 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 77 |
2 files changed, 90 insertions, 8 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 011003f04253..99fc8b899648 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -134,6 +134,15 @@ | |||
134 | ISER_MAX_TX_MISC_PDUS + \ | 134 | ISER_MAX_TX_MISC_PDUS + \ |
135 | ISER_MAX_RX_MISC_PDUS) | 135 | ISER_MAX_RX_MISC_PDUS) |
136 | 136 | ||
137 | /* Max registration work requests per command */ | ||
138 | #define ISER_MAX_REG_WR_PER_CMD 5 | ||
139 | |||
140 | /* For Signature we don't support DATAOUTs so no need to make room for them */ | ||
141 | #define ISER_QP_SIG_MAX_REQ_DTOS (ISER_DEF_XMIT_CMDS_MAX * \ | ||
142 | (1 + ISER_MAX_REG_WR_PER_CMD) + \ | ||
143 | ISER_MAX_TX_MISC_PDUS + \ | ||
144 | ISER_MAX_RX_MISC_PDUS) | ||
145 | |||
137 | #define ISER_VER 0x10 | 146 | #define ISER_VER 0x10 |
138 | #define ISER_WSV 0x08 | 147 | #define ISER_WSV 0x08 |
139 | #define ISER_RSV 0x04 | 148 | #define ISER_RSV 0x04 |
@@ -281,7 +290,16 @@ struct iser_device { | |||
281 | }; | 290 | }; |
282 | 291 | ||
283 | enum iser_reg_indicator { | 292 | enum iser_reg_indicator { |
284 | ISER_DATA_KEY_VALID = 1 << 0, | 293 | ISER_DATA_KEY_VALID = 1 << 0, |
294 | ISER_PROT_KEY_VALID = 1 << 1, | ||
295 | ISER_SIG_KEY_VALID = 1 << 2, | ||
296 | ISER_FASTREG_PROTECTED = 1 << 3, | ||
297 | }; | ||
298 | |||
299 | struct iser_pi_context { | ||
300 | struct ib_mr *prot_mr; | ||
301 | struct ib_fast_reg_page_list *prot_frpl; | ||
302 | struct ib_mr *sig_mr; | ||
285 | }; | 303 | }; |
286 | 304 | ||
287 | struct fast_reg_descriptor { | 305 | struct fast_reg_descriptor { |
@@ -289,6 +307,7 @@ struct fast_reg_descriptor { | |||
289 | /* For fast registration - FRWR */ | 307 | /* For fast registration - FRWR */ |
290 | struct ib_mr *data_mr; | 308 | struct ib_mr *data_mr; |
291 | struct ib_fast_reg_page_list *data_frpl; | 309 | struct ib_fast_reg_page_list *data_frpl; |
310 | struct iser_pi_context *pi_ctx; | ||
292 | /* registration indicators container */ | 311 | /* registration indicators container */ |
293 | u8 reg_indicators; | 312 | u8 reg_indicators; |
294 | }; | 313 | }; |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 4c27f553df39..0404c71761f9 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -275,7 +275,7 @@ void iser_free_fmr_pool(struct iser_conn *ib_conn) | |||
275 | 275 | ||
276 | static int | 276 | static int |
277 | iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd, | 277 | iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd, |
278 | struct fast_reg_descriptor *desc) | 278 | bool pi_enable, struct fast_reg_descriptor *desc) |
279 | { | 279 | { |
280 | int ret; | 280 | int ret; |
281 | 281 | ||
@@ -294,12 +294,64 @@ iser_create_fastreg_desc(struct ib_device *ib_device, struct ib_pd *pd, | |||
294 | iser_err("Failed to allocate ib_fast_reg_mr err=%d\n", ret); | 294 | iser_err("Failed to allocate ib_fast_reg_mr err=%d\n", ret); |
295 | goto fast_reg_mr_failure; | 295 | goto fast_reg_mr_failure; |
296 | } | 296 | } |
297 | desc->reg_indicators |= ISER_DATA_KEY_VALID; | ||
298 | |||
299 | if (pi_enable) { | ||
300 | struct ib_mr_init_attr mr_init_attr = {0}; | ||
301 | struct iser_pi_context *pi_ctx = NULL; | ||
302 | |||
303 | desc->pi_ctx = kzalloc(sizeof(*desc->pi_ctx), GFP_KERNEL); | ||
304 | if (!desc->pi_ctx) { | ||
305 | iser_err("Failed to allocate pi context\n"); | ||
306 | ret = -ENOMEM; | ||
307 | goto pi_ctx_alloc_failure; | ||
308 | } | ||
309 | pi_ctx = desc->pi_ctx; | ||
310 | |||
311 | pi_ctx->prot_frpl = ib_alloc_fast_reg_page_list(ib_device, | ||
312 | ISCSI_ISER_SG_TABLESIZE); | ||
313 | if (IS_ERR(pi_ctx->prot_frpl)) { | ||
314 | ret = PTR_ERR(pi_ctx->prot_frpl); | ||
315 | iser_err("Failed to allocate prot frpl ret=%d\n", | ||
316 | ret); | ||
317 | goto prot_frpl_failure; | ||
318 | } | ||
319 | |||
320 | pi_ctx->prot_mr = ib_alloc_fast_reg_mr(pd, | ||
321 | ISCSI_ISER_SG_TABLESIZE + 1); | ||
322 | if (IS_ERR(pi_ctx->prot_mr)) { | ||
323 | ret = PTR_ERR(pi_ctx->prot_mr); | ||
324 | iser_err("Failed to allocate prot frmr ret=%d\n", | ||
325 | ret); | ||
326 | goto prot_mr_failure; | ||
327 | } | ||
328 | desc->reg_indicators |= ISER_PROT_KEY_VALID; | ||
329 | |||
330 | mr_init_attr.max_reg_descriptors = 2; | ||
331 | mr_init_attr.flags |= IB_MR_SIGNATURE_EN; | ||
332 | pi_ctx->sig_mr = ib_create_mr(pd, &mr_init_attr); | ||
333 | if (IS_ERR(pi_ctx->sig_mr)) { | ||
334 | ret = PTR_ERR(pi_ctx->sig_mr); | ||
335 | iser_err("Failed to allocate signature enabled mr err=%d\n", | ||
336 | ret); | ||
337 | goto sig_mr_failure; | ||
338 | } | ||
339 | desc->reg_indicators |= ISER_SIG_KEY_VALID; | ||
340 | } | ||
341 | desc->reg_indicators &= ~ISER_FASTREG_PROTECTED; | ||
342 | |||
297 | iser_info("Create fr_desc %p page_list %p\n", | 343 | iser_info("Create fr_desc %p page_list %p\n", |
298 | desc, desc->data_frpl->page_list); | 344 | desc, desc->data_frpl->page_list); |
299 | desc->reg_indicators |= ISER_DATA_KEY_VALID; | ||
300 | 345 | ||
301 | return 0; | 346 | return 0; |
302 | 347 | sig_mr_failure: | |
348 | ib_dereg_mr(desc->pi_ctx->prot_mr); | ||
349 | prot_mr_failure: | ||
350 | ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl); | ||
351 | prot_frpl_failure: | ||
352 | kfree(desc->pi_ctx); | ||
353 | pi_ctx_alloc_failure: | ||
354 | ib_dereg_mr(desc->data_mr); | ||
303 | fast_reg_mr_failure: | 355 | fast_reg_mr_failure: |
304 | ib_free_fast_reg_page_list(desc->data_frpl); | 356 | ib_free_fast_reg_page_list(desc->data_frpl); |
305 | 357 | ||
@@ -320,15 +372,15 @@ int iser_create_fastreg_pool(struct iser_conn *ib_conn, unsigned cmds_max) | |||
320 | INIT_LIST_HEAD(&ib_conn->fastreg.pool); | 372 | INIT_LIST_HEAD(&ib_conn->fastreg.pool); |
321 | ib_conn->fastreg.pool_size = 0; | 373 | ib_conn->fastreg.pool_size = 0; |
322 | for (i = 0; i < cmds_max; i++) { | 374 | for (i = 0; i < cmds_max; i++) { |
323 | desc = kmalloc(sizeof(*desc), GFP_KERNEL); | 375 | desc = kzalloc(sizeof(*desc), GFP_KERNEL); |
324 | if (!desc) { | 376 | if (!desc) { |
325 | iser_err("Failed to allocate a new fast_reg descriptor\n"); | 377 | iser_err("Failed to allocate a new fast_reg descriptor\n"); |
326 | ret = -ENOMEM; | 378 | ret = -ENOMEM; |
327 | goto err; | 379 | goto err; |
328 | } | 380 | } |
329 | 381 | ||
330 | ret = iser_create_fastreg_desc(device->ib_device, | 382 | ret = iser_create_fastreg_desc(device->ib_device, device->pd, |
331 | device->pd, desc); | 383 | ib_conn->pi_support, desc); |
332 | if (ret) { | 384 | if (ret) { |
333 | iser_err("Failed to create fastreg descriptor err=%d\n", | 385 | iser_err("Failed to create fastreg descriptor err=%d\n", |
334 | ret); | 386 | ret); |
@@ -364,6 +416,12 @@ void iser_free_fastreg_pool(struct iser_conn *ib_conn) | |||
364 | list_del(&desc->list); | 416 | list_del(&desc->list); |
365 | ib_free_fast_reg_page_list(desc->data_frpl); | 417 | ib_free_fast_reg_page_list(desc->data_frpl); |
366 | ib_dereg_mr(desc->data_mr); | 418 | ib_dereg_mr(desc->data_mr); |
419 | if (desc->pi_ctx) { | ||
420 | ib_free_fast_reg_page_list(desc->pi_ctx->prot_frpl); | ||
421 | ib_dereg_mr(desc->pi_ctx->prot_mr); | ||
422 | ib_destroy_mr(desc->pi_ctx->sig_mr); | ||
423 | kfree(desc->pi_ctx); | ||
424 | } | ||
367 | kfree(desc); | 425 | kfree(desc); |
368 | ++i; | 426 | ++i; |
369 | } | 427 | } |
@@ -405,12 +463,17 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
405 | init_attr.qp_context = (void *)ib_conn; | 463 | init_attr.qp_context = (void *)ib_conn; |
406 | init_attr.send_cq = device->tx_cq[min_index]; | 464 | init_attr.send_cq = device->tx_cq[min_index]; |
407 | init_attr.recv_cq = device->rx_cq[min_index]; | 465 | init_attr.recv_cq = device->rx_cq[min_index]; |
408 | init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; | ||
409 | init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; | 466 | init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS; |
410 | init_attr.cap.max_send_sge = 2; | 467 | init_attr.cap.max_send_sge = 2; |
411 | init_attr.cap.max_recv_sge = 1; | 468 | init_attr.cap.max_recv_sge = 1; |
412 | init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; | 469 | init_attr.sq_sig_type = IB_SIGNAL_REQ_WR; |
413 | init_attr.qp_type = IB_QPT_RC; | 470 | init_attr.qp_type = IB_QPT_RC; |
471 | if (ib_conn->pi_support) { | ||
472 | init_attr.cap.max_send_wr = ISER_QP_SIG_MAX_REQ_DTOS; | ||
473 | init_attr.create_flags |= IB_QP_CREATE_SIGNATURE_EN; | ||
474 | } else { | ||
475 | init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS; | ||
476 | } | ||
414 | 477 | ||
415 | ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); | 478 | ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr); |
416 | if (ret) | 479 | if (ret) |