diff options
author | Bart Van Assche <bart.vanassche@wdc.com> | 2017-11-03 19:20:53 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-11-13 15:25:16 -0500 |
commit | c76d7d64f8067699260421509a7c11ad51761061 (patch) | |
tree | 6f347bec595f0a665f14c13fe54d7375d288068d | |
parent | 321e329b9c0b3328e3f6bd4924b9c8c5cbf5c22d (diff) |
IB/srpt: Introduce helper functions for SRQ allocation and freeing
The only functional change in this patch is in the srpt_add_one()
error path: if allocating the ring buffer for the SRQ fails, fall
back to non-SRQ mode instead of disabling SRP target functionality.
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/ulp/srpt/ib_srpt.c | 115 |
1 files changed, 72 insertions, 43 deletions
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 98b1b80e476b..a5f232e9b1f3 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -2510,6 +2510,74 @@ static struct se_wwn *srpt_lookup_wwn(const char *name) | |||
2510 | return wwn; | 2510 | return wwn; |
2511 | } | 2511 | } |
2512 | 2512 | ||
2513 | static void srpt_free_srq(struct srpt_device *sdev) | ||
2514 | { | ||
2515 | if (!sdev->srq) | ||
2516 | return; | ||
2517 | |||
2518 | ib_destroy_srq(sdev->srq); | ||
2519 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, | ||
2520 | sdev->srq_size, srp_max_req_size, DMA_FROM_DEVICE); | ||
2521 | sdev->srq = NULL; | ||
2522 | } | ||
2523 | |||
2524 | static int srpt_alloc_srq(struct srpt_device *sdev) | ||
2525 | { | ||
2526 | struct ib_srq_init_attr srq_attr = { | ||
2527 | .event_handler = srpt_srq_event, | ||
2528 | .srq_context = (void *)sdev, | ||
2529 | .attr.max_wr = sdev->srq_size, | ||
2530 | .attr.max_sge = 1, | ||
2531 | .srq_type = IB_SRQT_BASIC, | ||
2532 | }; | ||
2533 | struct ib_device *device = sdev->device; | ||
2534 | struct ib_srq *srq; | ||
2535 | int i; | ||
2536 | |||
2537 | WARN_ON_ONCE(sdev->srq); | ||
2538 | srq = ib_create_srq(sdev->pd, &srq_attr); | ||
2539 | if (IS_ERR(srq)) { | ||
2540 | pr_debug("ib_create_srq() failed: %ld\n", PTR_ERR(srq)); | ||
2541 | return PTR_ERR(srq); | ||
2542 | } | ||
2543 | |||
2544 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size, | ||
2545 | sdev->device->attrs.max_srq_wr, device->name); | ||
2546 | |||
2547 | sdev->ioctx_ring = (struct srpt_recv_ioctx **) | ||
2548 | srpt_alloc_ioctx_ring(sdev, sdev->srq_size, | ||
2549 | sizeof(*sdev->ioctx_ring[0]), | ||
2550 | srp_max_req_size, DMA_FROM_DEVICE); | ||
2551 | if (!sdev->ioctx_ring) { | ||
2552 | ib_destroy_srq(srq); | ||
2553 | return -ENOMEM; | ||
2554 | } | ||
2555 | |||
2556 | sdev->use_srq = true; | ||
2557 | sdev->srq = srq; | ||
2558 | |||
2559 | for (i = 0; i < sdev->srq_size; ++i) | ||
2560 | srpt_post_recv(sdev, NULL, sdev->ioctx_ring[i]); | ||
2561 | |||
2562 | return 0; | ||
2563 | } | ||
2564 | |||
2565 | static int srpt_use_srq(struct srpt_device *sdev, bool use_srq) | ||
2566 | { | ||
2567 | struct ib_device *device = sdev->device; | ||
2568 | int ret = 0; | ||
2569 | |||
2570 | if (!use_srq) { | ||
2571 | srpt_free_srq(sdev); | ||
2572 | sdev->use_srq = false; | ||
2573 | } else if (use_srq && !sdev->srq) { | ||
2574 | ret = srpt_alloc_srq(sdev); | ||
2575 | } | ||
2576 | pr_debug("%s(%s): use_srq = %d; ret = %d\n", __func__, device->name, | ||
2577 | sdev->use_srq, ret); | ||
2578 | return ret; | ||
2579 | } | ||
2580 | |||
2513 | /** | 2581 | /** |
2514 | * srpt_add_one() - Infiniband device addition callback function. | 2582 | * srpt_add_one() - Infiniband device addition callback function. |
2515 | */ | 2583 | */ |
@@ -2517,7 +2585,6 @@ static void srpt_add_one(struct ib_device *device) | |||
2517 | { | 2585 | { |
2518 | struct srpt_device *sdev; | 2586 | struct srpt_device *sdev; |
2519 | struct srpt_port *sport; | 2587 | struct srpt_port *sport; |
2520 | struct ib_srq_init_attr srq_attr; | ||
2521 | int i; | 2588 | int i; |
2522 | 2589 | ||
2523 | pr_debug("device = %p\n", device); | 2590 | pr_debug("device = %p\n", device); |
@@ -2539,38 +2606,7 @@ static void srpt_add_one(struct ib_device *device) | |||
2539 | 2606 | ||
2540 | sdev->srq_size = min(srpt_srq_size, sdev->device->attrs.max_srq_wr); | 2607 | sdev->srq_size = min(srpt_srq_size, sdev->device->attrs.max_srq_wr); |
2541 | 2608 | ||
2542 | srq_attr.event_handler = srpt_srq_event; | 2609 | srpt_use_srq(sdev, sdev->port[0].port_attrib.use_srq); |
2543 | srq_attr.srq_context = (void *)sdev; | ||
2544 | srq_attr.attr.max_wr = sdev->srq_size; | ||
2545 | srq_attr.attr.max_sge = 1; | ||
2546 | srq_attr.attr.srq_limit = 0; | ||
2547 | srq_attr.srq_type = IB_SRQT_BASIC; | ||
2548 | |||
2549 | sdev->srq = sdev->port[0].port_attrib.use_srq ? | ||
2550 | ib_create_srq(sdev->pd, &srq_attr) : ERR_PTR(-ENOTSUPP); | ||
2551 | if (IS_ERR(sdev->srq)) { | ||
2552 | pr_debug("ib_create_srq() failed: %ld\n", PTR_ERR(sdev->srq)); | ||
2553 | |||
2554 | /* SRQ not supported. */ | ||
2555 | sdev->use_srq = false; | ||
2556 | } else { | ||
2557 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", | ||
2558 | sdev->srq_size, sdev->device->attrs.max_srq_wr, | ||
2559 | device->name); | ||
2560 | |||
2561 | sdev->use_srq = true; | ||
2562 | |||
2563 | sdev->ioctx_ring = (struct srpt_recv_ioctx **) | ||
2564 | srpt_alloc_ioctx_ring(sdev, sdev->srq_size, | ||
2565 | sizeof(*sdev->ioctx_ring[0]), | ||
2566 | srp_max_req_size, | ||
2567 | DMA_FROM_DEVICE); | ||
2568 | if (!sdev->ioctx_ring) | ||
2569 | goto err_pd; | ||
2570 | |||
2571 | for (i = 0; i < sdev->srq_size; ++i) | ||
2572 | srpt_post_recv(sdev, NULL, sdev->ioctx_ring[i]); | ||
2573 | } | ||
2574 | 2610 | ||
2575 | if (!srpt_service_guid) | 2611 | if (!srpt_service_guid) |
2576 | srpt_service_guid = be64_to_cpu(device->node_guid); | 2612 | srpt_service_guid = be64_to_cpu(device->node_guid); |
@@ -2630,12 +2666,7 @@ err_event: | |||
2630 | err_cm: | 2666 | err_cm: |
2631 | ib_destroy_cm_id(sdev->cm_id); | 2667 | ib_destroy_cm_id(sdev->cm_id); |
2632 | err_ring: | 2668 | err_ring: |
2633 | if (sdev->use_srq) | 2669 | srpt_free_srq(sdev); |
2634 | ib_destroy_srq(sdev->srq); | ||
2635 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, | ||
2636 | sdev->srq_size, srp_max_req_size, | ||
2637 | DMA_FROM_DEVICE); | ||
2638 | err_pd: | ||
2639 | ib_dealloc_pd(sdev->pd); | 2670 | ib_dealloc_pd(sdev->pd); |
2640 | free_dev: | 2671 | free_dev: |
2641 | kfree(sdev); | 2672 | kfree(sdev); |
@@ -2678,10 +2709,8 @@ static void srpt_remove_one(struct ib_device *device, void *client_data) | |||
2678 | spin_unlock(&srpt_dev_lock); | 2709 | spin_unlock(&srpt_dev_lock); |
2679 | srpt_release_sdev(sdev); | 2710 | srpt_release_sdev(sdev); |
2680 | 2711 | ||
2681 | if (sdev->use_srq) | 2712 | srpt_free_srq(sdev); |
2682 | ib_destroy_srq(sdev->srq); | 2713 | |
2683 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, | ||
2684 | sdev->srq_size, srp_max_req_size, DMA_FROM_DEVICE); | ||
2685 | ib_dealloc_pd(sdev->pd); | 2714 | ib_dealloc_pd(sdev->pd); |
2686 | 2715 | ||
2687 | kfree(sdev); | 2716 | kfree(sdev); |