diff options
author | Sagi Grimberg <sagig@mellanox.com> | 2014-02-19 10:50:23 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-07 04:48:46 -0400 |
commit | d3e125dac1f4fd983bb6d8d654f152f243f7c953 (patch) | |
tree | ecc27fe131922564c177349f48987b14e852b37e /drivers/infiniband/ulp | |
parent | e3d7e4c30c494431d492864448fbb16cdd7a6178 (diff) |
IB/isert: Initialize T10-PI resources
Introduce pi_context to hold relevant RDMA protection resources.
We eliminate data_key_valid boolean and replace it with indicators
container to indicate:
- Is the descriptor protected (registered via signature MR)
- Is the data_mr key valid (can spare LOCAL_INV WR)
- Is the prot_mr key valid (can spare LOCAL_INV WR)
- Is the sig_mr key valid (can spare LOCAL_INV WR)
Upon connection establishment check if network portal is T10-PI
enabled and allocate T10-PI resources if necessary, allocate
signature enabled memory regions and mark connection queue-pair
as signature enabled.
(Fix context change for v3.14-rc6 code - nab)
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 104 | ||||
-rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.h | 23 |
2 files changed, 110 insertions, 17 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index d0ca3328aa4d..72063147933c 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -87,7 +87,8 @@ isert_query_device(struct ib_device *ib_dev, struct ib_device_attr *devattr) | |||
87 | } | 87 | } |
88 | 88 | ||
89 | static int | 89 | static int |
90 | isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id) | 90 | isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id, |
91 | u8 protection) | ||
91 | { | 92 | { |
92 | struct isert_device *device = isert_conn->conn_device; | 93 | struct isert_device *device = isert_conn->conn_device; |
93 | struct ib_qp_init_attr attr; | 94 | struct ib_qp_init_attr attr; |
@@ -119,6 +120,8 @@ isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id) | |||
119 | attr.cap.max_recv_sge = 1; | 120 | attr.cap.max_recv_sge = 1; |
120 | attr.sq_sig_type = IB_SIGNAL_REQ_WR; | 121 | attr.sq_sig_type = IB_SIGNAL_REQ_WR; |
121 | attr.qp_type = IB_QPT_RC; | 122 | attr.qp_type = IB_QPT_RC; |
123 | if (protection) | ||
124 | attr.create_flags |= IB_QP_CREATE_SIGNATURE_EN; | ||
122 | 125 | ||
123 | pr_debug("isert_conn_setup_qp cma_id->device: %p\n", | 126 | pr_debug("isert_conn_setup_qp cma_id->device: %p\n", |
124 | cma_id->device); | 127 | cma_id->device); |
@@ -236,13 +239,18 @@ isert_create_device_ib_res(struct isert_device *device) | |||
236 | device->unreg_rdma_mem = isert_unmap_cmd; | 239 | device->unreg_rdma_mem = isert_unmap_cmd; |
237 | } | 240 | } |
238 | 241 | ||
242 | /* Check signature cap */ | ||
243 | device->pi_capable = dev_attr->device_cap_flags & | ||
244 | IB_DEVICE_SIGNATURE_HANDOVER ? true : false; | ||
245 | |||
239 | device->cqs_used = min_t(int, num_online_cpus(), | 246 | device->cqs_used = min_t(int, num_online_cpus(), |
240 | device->ib_device->num_comp_vectors); | 247 | device->ib_device->num_comp_vectors); |
241 | device->cqs_used = min(ISERT_MAX_CQ, device->cqs_used); | 248 | device->cqs_used = min(ISERT_MAX_CQ, device->cqs_used); |
242 | pr_debug("Using %d CQs, device %s supports %d vectors support " | 249 | pr_debug("Using %d CQs, device %s supports %d vectors support " |
243 | "Fast registration %d\n", | 250 | "Fast registration %d pi_capable %d\n", |
244 | device->cqs_used, device->ib_device->name, | 251 | device->cqs_used, device->ib_device->name, |
245 | device->ib_device->num_comp_vectors, device->use_fastreg); | 252 | device->ib_device->num_comp_vectors, device->use_fastreg, |
253 | device->pi_capable); | ||
246 | device->cq_desc = kzalloc(sizeof(struct isert_cq_desc) * | 254 | device->cq_desc = kzalloc(sizeof(struct isert_cq_desc) * |
247 | device->cqs_used, GFP_KERNEL); | 255 | device->cqs_used, GFP_KERNEL); |
248 | if (!device->cq_desc) { | 256 | if (!device->cq_desc) { |
@@ -395,6 +403,12 @@ isert_conn_free_fastreg_pool(struct isert_conn *isert_conn) | |||
395 | list_del(&fr_desc->list); | 403 | list_del(&fr_desc->list); |
396 | ib_free_fast_reg_page_list(fr_desc->data_frpl); | 404 | ib_free_fast_reg_page_list(fr_desc->data_frpl); |
397 | ib_dereg_mr(fr_desc->data_mr); | 405 | ib_dereg_mr(fr_desc->data_mr); |
406 | if (fr_desc->pi_ctx) { | ||
407 | ib_free_fast_reg_page_list(fr_desc->pi_ctx->prot_frpl); | ||
408 | ib_dereg_mr(fr_desc->pi_ctx->prot_mr); | ||
409 | ib_destroy_mr(fr_desc->pi_ctx->sig_mr); | ||
410 | kfree(fr_desc->pi_ctx); | ||
411 | } | ||
398 | kfree(fr_desc); | 412 | kfree(fr_desc); |
399 | ++i; | 413 | ++i; |
400 | } | 414 | } |
@@ -406,8 +420,10 @@ isert_conn_free_fastreg_pool(struct isert_conn *isert_conn) | |||
406 | 420 | ||
407 | static int | 421 | static int |
408 | isert_create_fr_desc(struct ib_device *ib_device, struct ib_pd *pd, | 422 | isert_create_fr_desc(struct ib_device *ib_device, struct ib_pd *pd, |
409 | struct fast_reg_descriptor *fr_desc) | 423 | struct fast_reg_descriptor *fr_desc, u8 protection) |
410 | { | 424 | { |
425 | int ret; | ||
426 | |||
411 | fr_desc->data_frpl = ib_alloc_fast_reg_page_list(ib_device, | 427 | fr_desc->data_frpl = ib_alloc_fast_reg_page_list(ib_device, |
412 | ISCSI_ISER_SG_TABLESIZE); | 428 | ISCSI_ISER_SG_TABLESIZE); |
413 | if (IS_ERR(fr_desc->data_frpl)) { | 429 | if (IS_ERR(fr_desc->data_frpl)) { |
@@ -420,19 +436,73 @@ isert_create_fr_desc(struct ib_device *ib_device, struct ib_pd *pd, | |||
420 | if (IS_ERR(fr_desc->data_mr)) { | 436 | if (IS_ERR(fr_desc->data_mr)) { |
421 | pr_err("Failed to allocate data frmr err=%ld\n", | 437 | pr_err("Failed to allocate data frmr err=%ld\n", |
422 | PTR_ERR(fr_desc->data_mr)); | 438 | PTR_ERR(fr_desc->data_mr)); |
423 | ib_free_fast_reg_page_list(fr_desc->data_frpl); | 439 | ret = PTR_ERR(fr_desc->data_mr); |
424 | return PTR_ERR(fr_desc->data_mr); | 440 | goto err_data_frpl; |
425 | } | 441 | } |
426 | pr_debug("Create fr_desc %p page_list %p\n", | 442 | pr_debug("Create fr_desc %p page_list %p\n", |
427 | fr_desc, fr_desc->data_frpl->page_list); | 443 | fr_desc, fr_desc->data_frpl->page_list); |
444 | fr_desc->ind |= ISERT_DATA_KEY_VALID; | ||
428 | 445 | ||
429 | fr_desc->valid = true; | 446 | if (protection) { |
447 | struct ib_mr_init_attr mr_init_attr = {0}; | ||
448 | struct pi_context *pi_ctx; | ||
449 | |||
450 | fr_desc->pi_ctx = kzalloc(sizeof(*fr_desc->pi_ctx), GFP_KERNEL); | ||
451 | if (!fr_desc->pi_ctx) { | ||
452 | pr_err("Failed to allocate pi context\n"); | ||
453 | ret = -ENOMEM; | ||
454 | goto err_data_mr; | ||
455 | } | ||
456 | pi_ctx = fr_desc->pi_ctx; | ||
457 | |||
458 | pi_ctx->prot_frpl = ib_alloc_fast_reg_page_list(ib_device, | ||
459 | ISCSI_ISER_SG_TABLESIZE); | ||
460 | if (IS_ERR(pi_ctx->prot_frpl)) { | ||
461 | pr_err("Failed to allocate prot frpl err=%ld\n", | ||
462 | PTR_ERR(pi_ctx->prot_frpl)); | ||
463 | ret = PTR_ERR(pi_ctx->prot_frpl); | ||
464 | goto err_pi_ctx; | ||
465 | } | ||
466 | |||
467 | pi_ctx->prot_mr = ib_alloc_fast_reg_mr(pd, ISCSI_ISER_SG_TABLESIZE); | ||
468 | if (IS_ERR(pi_ctx->prot_mr)) { | ||
469 | pr_err("Failed to allocate prot frmr err=%ld\n", | ||
470 | PTR_ERR(pi_ctx->prot_mr)); | ||
471 | ret = PTR_ERR(pi_ctx->prot_mr); | ||
472 | goto err_prot_frpl; | ||
473 | } | ||
474 | fr_desc->ind |= ISERT_PROT_KEY_VALID; | ||
475 | |||
476 | mr_init_attr.max_reg_descriptors = 2; | ||
477 | mr_init_attr.flags |= IB_MR_SIGNATURE_EN; | ||
478 | pi_ctx->sig_mr = ib_create_mr(pd, &mr_init_attr); | ||
479 | if (IS_ERR(pi_ctx->sig_mr)) { | ||
480 | pr_err("Failed to allocate signature enabled mr err=%ld\n", | ||
481 | PTR_ERR(pi_ctx->sig_mr)); | ||
482 | ret = PTR_ERR(pi_ctx->sig_mr); | ||
483 | goto err_prot_mr; | ||
484 | } | ||
485 | fr_desc->ind |= ISERT_SIG_KEY_VALID; | ||
486 | } | ||
487 | fr_desc->ind &= ~ISERT_PROTECTED; | ||
430 | 488 | ||
431 | return 0; | 489 | return 0; |
490 | err_prot_mr: | ||
491 | ib_dereg_mr(fr_desc->pi_ctx->prot_mr); | ||
492 | err_prot_frpl: | ||
493 | ib_free_fast_reg_page_list(fr_desc->pi_ctx->prot_frpl); | ||
494 | err_pi_ctx: | ||
495 | kfree(fr_desc->pi_ctx); | ||
496 | err_data_mr: | ||
497 | ib_dereg_mr(fr_desc->data_mr); | ||
498 | err_data_frpl: | ||
499 | ib_free_fast_reg_page_list(fr_desc->data_frpl); | ||
500 | |||
501 | return ret; | ||
432 | } | 502 | } |
433 | 503 | ||
434 | static int | 504 | static int |
435 | isert_conn_create_fastreg_pool(struct isert_conn *isert_conn) | 505 | isert_conn_create_fastreg_pool(struct isert_conn *isert_conn, u8 pi_support) |
436 | { | 506 | { |
437 | struct fast_reg_descriptor *fr_desc; | 507 | struct fast_reg_descriptor *fr_desc; |
438 | struct isert_device *device = isert_conn->conn_device; | 508 | struct isert_device *device = isert_conn->conn_device; |
@@ -449,7 +519,8 @@ isert_conn_create_fastreg_pool(struct isert_conn *isert_conn) | |||
449 | } | 519 | } |
450 | 520 | ||
451 | ret = isert_create_fr_desc(device->ib_device, | 521 | ret = isert_create_fr_desc(device->ib_device, |
452 | isert_conn->conn_pd, fr_desc); | 522 | isert_conn->conn_pd, fr_desc, |
523 | pi_support); | ||
453 | if (ret) { | 524 | if (ret) { |
454 | pr_err("Failed to create fastreg descriptor err=%d\n", | 525 | pr_err("Failed to create fastreg descriptor err=%d\n", |
455 | ret); | 526 | ret); |
@@ -480,6 +551,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
480 | struct isert_device *device; | 551 | struct isert_device *device; |
481 | struct ib_device *ib_dev = cma_id->device; | 552 | struct ib_device *ib_dev = cma_id->device; |
482 | int ret = 0; | 553 | int ret = 0; |
554 | u8 pi_support = np->tpg_np->tpg->tpg_attrib.t10_pi; | ||
483 | 555 | ||
484 | pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n", | 556 | pr_debug("Entering isert_connect_request cma_id: %p, context: %p\n", |
485 | cma_id, cma_id->context); | 557 | cma_id, cma_id->context); |
@@ -569,8 +641,14 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
569 | goto out_mr; | 641 | goto out_mr; |
570 | } | 642 | } |
571 | 643 | ||
644 | if (pi_support && !device->pi_capable) { | ||
645 | pr_err("Protection information requested but not supported\n"); | ||
646 | ret = -EINVAL; | ||
647 | goto out_mr; | ||
648 | } | ||
649 | |||
572 | if (device->use_fastreg) { | 650 | if (device->use_fastreg) { |
573 | ret = isert_conn_create_fastreg_pool(isert_conn); | 651 | ret = isert_conn_create_fastreg_pool(isert_conn, pi_support); |
574 | if (ret) { | 652 | if (ret) { |
575 | pr_err("Conn: %p failed to create fastreg pool\n", | 653 | pr_err("Conn: %p failed to create fastreg pool\n", |
576 | isert_conn); | 654 | isert_conn); |
@@ -578,7 +656,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
578 | } | 656 | } |
579 | } | 657 | } |
580 | 658 | ||
581 | ret = isert_conn_setup_qp(isert_conn, cma_id); | 659 | ret = isert_conn_setup_qp(isert_conn, cma_id, pi_support); |
582 | if (ret) | 660 | if (ret) |
583 | goto out_conn_dev; | 661 | goto out_conn_dev; |
584 | 662 | ||
@@ -2280,7 +2358,7 @@ isert_fast_reg_mr(struct isert_conn *isert_conn, | |||
2280 | pagelist_len = isert_map_fr_pagelist(ib_dev, mem->sg, mem->nents, | 2358 | pagelist_len = isert_map_fr_pagelist(ib_dev, mem->sg, mem->nents, |
2281 | &fr_desc->data_frpl->page_list[0]); | 2359 | &fr_desc->data_frpl->page_list[0]); |
2282 | 2360 | ||
2283 | if (!fr_desc->valid) { | 2361 | if (!(fr_desc->ind & ISERT_DATA_KEY_VALID)) { |
2284 | memset(&inv_wr, 0, sizeof(inv_wr)); | 2362 | memset(&inv_wr, 0, sizeof(inv_wr)); |
2285 | inv_wr.wr_id = ISER_FASTREG_LI_WRID; | 2363 | inv_wr.wr_id = ISER_FASTREG_LI_WRID; |
2286 | inv_wr.opcode = IB_WR_LOCAL_INV; | 2364 | inv_wr.opcode = IB_WR_LOCAL_INV; |
@@ -2314,7 +2392,7 @@ isert_fast_reg_mr(struct isert_conn *isert_conn, | |||
2314 | pr_err("fast registration failed, ret:%d\n", ret); | 2392 | pr_err("fast registration failed, ret:%d\n", ret); |
2315 | return ret; | 2393 | return ret; |
2316 | } | 2394 | } |
2317 | fr_desc->valid = false; | 2395 | fr_desc->ind &= ~ISERT_DATA_KEY_VALID; |
2318 | 2396 | ||
2319 | sge->lkey = fr_desc->data_mr->lkey; | 2397 | sge->lkey = fr_desc->data_mr->lkey; |
2320 | sge->addr = fr_desc->data_frpl->page_list[0] + page_off; | 2398 | sge->addr = fr_desc->data_frpl->page_list[0] + page_off; |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 8a02c4ebe373..a75b75fbc9d1 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
@@ -50,11 +50,25 @@ struct iser_tx_desc { | |||
50 | struct ib_send_wr send_wr; | 50 | struct ib_send_wr send_wr; |
51 | } __packed; | 51 | } __packed; |
52 | 52 | ||
53 | enum isert_indicator { | ||
54 | ISERT_PROTECTED = 1 << 0, | ||
55 | ISERT_DATA_KEY_VALID = 1 << 1, | ||
56 | ISERT_PROT_KEY_VALID = 1 << 2, | ||
57 | ISERT_SIG_KEY_VALID = 1 << 3, | ||
58 | }; | ||
59 | |||
60 | struct pi_context { | ||
61 | struct ib_mr *prot_mr; | ||
62 | struct ib_fast_reg_page_list *prot_frpl; | ||
63 | struct ib_mr *sig_mr; | ||
64 | }; | ||
65 | |||
53 | struct fast_reg_descriptor { | 66 | struct fast_reg_descriptor { |
54 | struct list_head list; | 67 | struct list_head list; |
55 | struct ib_mr *data_mr; | 68 | struct ib_mr *data_mr; |
56 | struct ib_fast_reg_page_list *data_frpl; | 69 | struct ib_fast_reg_page_list *data_frpl; |
57 | bool valid; | 70 | u8 ind; |
71 | struct pi_context *pi_ctx; | ||
58 | }; | 72 | }; |
59 | 73 | ||
60 | struct isert_data_buf { | 74 | struct isert_data_buf { |
@@ -149,6 +163,7 @@ struct isert_cq_desc { | |||
149 | 163 | ||
150 | struct isert_device { | 164 | struct isert_device { |
151 | int use_fastreg; | 165 | int use_fastreg; |
166 | bool pi_capable; | ||
152 | int cqs_used; | 167 | int cqs_used; |
153 | int refcount; | 168 | int refcount; |
154 | int cq_active_qps[ISERT_MAX_CQ]; | 169 | int cq_active_qps[ISERT_MAX_CQ]; |