aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@wdc.com>2017-11-03 19:20:53 -0400
committerDoug Ledford <dledford@redhat.com>2017-11-13 15:25:16 -0500
commitc76d7d64f8067699260421509a7c11ad51761061 (patch)
tree6f347bec595f0a665f14c13fe54d7375d288068d
parent321e329b9c0b3328e3f6bd4924b9c8c5cbf5c22d (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.c115
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
2513static 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
2524static 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
2565static 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:
2630err_cm: 2666err_cm:
2631 ib_destroy_cm_id(sdev->cm_id); 2667 ib_destroy_cm_id(sdev->cm_id);
2632err_ring: 2668err_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);
2638err_pd:
2639 ib_dealloc_pd(sdev->pd); 2670 ib_dealloc_pd(sdev->pd);
2640free_dev: 2671free_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);