Skip to content

Commit 62ea8b7

Browse files
dcuidavem330
authored andcommitted
net: mana: Improve the HWC error handling
Currently when the HWC creation fails, the error handling is flawed, e.g. if mana_hwc_create_channel() -> mana_hwc_establish_channel() fails, the resources acquired in mana_hwc_init_queues() is not released. Enhance mana_hwc_destroy_channel() to do the proper cleanup work and call it accordingly. Signed-off-by: Dexuan Cui <[email protected]> Reviewed-by: Haiyang Zhang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3c37f35 commit 62ea8b7

File tree

2 files changed

+31
-44
lines changed

2 files changed

+31
-44
lines changed

drivers/net/ethernet/microsoft/mana/gdma_main.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,8 +1330,6 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
13301330

13311331
clean_up_gdma:
13321332
mana_hwc_destroy_channel(gc);
1333-
vfree(gc->cq_table);
1334-
gc->cq_table = NULL;
13351333
remove_irq:
13361334
mana_gd_remove_irqs(pdev);
13371335
unmap_bar:
@@ -1354,8 +1352,6 @@ static void mana_gd_remove(struct pci_dev *pdev)
13541352
mana_remove(&gc->mana);
13551353

13561354
mana_hwc_destroy_channel(gc);
1357-
vfree(gc->cq_table);
1358-
gc->cq_table = NULL;
13591355

13601356
mana_gd_remove_irqs(pdev);
13611357

drivers/net/ethernet/microsoft/mana/hw_channel.c

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,6 @@ static void mana_hwc_comp_event(void *ctx, struct gdma_queue *q_self)
309309

310310
static void mana_hwc_destroy_cq(struct gdma_context *gc, struct hwc_cq *hwc_cq)
311311
{
312-
if (!hwc_cq)
313-
return;
314-
315312
kfree(hwc_cq->comp_buf);
316313

317314
if (hwc_cq->gdma_cq)
@@ -446,9 +443,6 @@ static void mana_hwc_dealloc_dma_buf(struct hw_channel_context *hwc,
446443
static void mana_hwc_destroy_wq(struct hw_channel_context *hwc,
447444
struct hwc_wq *hwc_wq)
448445
{
449-
if (!hwc_wq)
450-
return;
451-
452446
mana_hwc_dealloc_dma_buf(hwc, hwc_wq->msg_buf);
453447

454448
if (hwc_wq->gdma_wq)
@@ -621,6 +615,7 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
621615
*max_req_msg_size = hwc->hwc_init_max_req_msg_size;
622616
*max_resp_msg_size = hwc->hwc_init_max_resp_msg_size;
623617

618+
/* Both were set in mana_hwc_init_event_handler(). */
624619
if (WARN_ON(cq->id >= gc->max_num_cqs))
625620
return -EPROTO;
626621

@@ -636,9 +631,6 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
636631
static int mana_hwc_init_queues(struct hw_channel_context *hwc, u16 q_depth,
637632
u32 max_req_msg_size, u32 max_resp_msg_size)
638633
{
639-
struct hwc_wq *hwc_rxq = NULL;
640-
struct hwc_wq *hwc_txq = NULL;
641-
struct hwc_cq *hwc_cq = NULL;
642634
int err;
643635

644636
err = mana_hwc_init_inflight_msg(hwc, q_depth);
@@ -651,44 +643,32 @@ static int mana_hwc_init_queues(struct hw_channel_context *hwc, u16 q_depth,
651643
err = mana_hwc_create_cq(hwc, q_depth * 2,
652644
mana_hwc_init_event_handler, hwc,
653645
mana_hwc_rx_event_handler, hwc,
654-
mana_hwc_tx_event_handler, hwc, &hwc_cq);
646+
mana_hwc_tx_event_handler, hwc, &hwc->cq);
655647
if (err) {
656648
dev_err(hwc->dev, "Failed to create HWC CQ: %d\n", err);
657649
goto out;
658650
}
659-
hwc->cq = hwc_cq;
660651

661652
err = mana_hwc_create_wq(hwc, GDMA_RQ, q_depth, max_req_msg_size,
662-
hwc_cq, &hwc_rxq);
653+
hwc->cq, &hwc->rxq);
663654
if (err) {
664655
dev_err(hwc->dev, "Failed to create HWC RQ: %d\n", err);
665656
goto out;
666657
}
667-
hwc->rxq = hwc_rxq;
668658

669659
err = mana_hwc_create_wq(hwc, GDMA_SQ, q_depth, max_resp_msg_size,
670-
hwc_cq, &hwc_txq);
660+
hwc->cq, &hwc->txq);
671661
if (err) {
672662
dev_err(hwc->dev, "Failed to create HWC SQ: %d\n", err);
673663
goto out;
674664
}
675-
hwc->txq = hwc_txq;
676665

677666
hwc->num_inflight_msg = q_depth;
678667
hwc->max_req_msg_size = max_req_msg_size;
679668

680669
return 0;
681670
out:
682-
if (hwc_txq)
683-
mana_hwc_destroy_wq(hwc, hwc_txq);
684-
685-
if (hwc_rxq)
686-
mana_hwc_destroy_wq(hwc, hwc_rxq);
687-
688-
if (hwc_cq)
689-
mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc_cq);
690-
691-
mana_gd_free_res_map(&hwc->inflight_msg_res);
671+
/* mana_hwc_create_channel() will do the cleanup.*/
692672
return err;
693673
}
694674

@@ -716,6 +696,9 @@ int mana_hwc_create_channel(struct gdma_context *gc)
716696
gd->pdid = INVALID_PDID;
717697
gd->doorbell = INVALID_DOORBELL;
718698

699+
/* mana_hwc_init_queues() only creates the required data structures,
700+
* and doesn't touch the HWC device.
701+
*/
719702
err = mana_hwc_init_queues(hwc, HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH,
720703
HW_CHANNEL_MAX_REQUEST_SIZE,
721704
HW_CHANNEL_MAX_RESPONSE_SIZE);
@@ -741,42 +724,50 @@ int mana_hwc_create_channel(struct gdma_context *gc)
741724

742725
return 0;
743726
out:
744-
kfree(hwc);
727+
mana_hwc_destroy_channel(gc);
745728
return err;
746729
}
747730

748731
void mana_hwc_destroy_channel(struct gdma_context *gc)
749732
{
750733
struct hw_channel_context *hwc = gc->hwc.driver_data;
751-
struct hwc_caller_ctx *ctx;
752734

753-
mana_smc_teardown_hwc(&gc->shm_channel, false);
735+
if (!hwc)
736+
return;
737+
738+
/* gc->max_num_cqs is set in mana_hwc_init_event_handler(). If it's
739+
* non-zero, the HWC worked and we should tear down the HWC here.
740+
*/
741+
if (gc->max_num_cqs > 0) {
742+
mana_smc_teardown_hwc(&gc->shm_channel, false);
743+
gc->max_num_cqs = 0;
744+
}
754745

755-
ctx = hwc->caller_ctx;
756-
kfree(ctx);
746+
kfree(hwc->caller_ctx);
757747
hwc->caller_ctx = NULL;
758748

759-
mana_hwc_destroy_wq(hwc, hwc->txq);
760-
hwc->txq = NULL;
749+
if (hwc->txq)
750+
mana_hwc_destroy_wq(hwc, hwc->txq);
761751

762-
mana_hwc_destroy_wq(hwc, hwc->rxq);
763-
hwc->rxq = NULL;
752+
if (hwc->rxq)
753+
mana_hwc_destroy_wq(hwc, hwc->rxq);
764754

765-
mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
766-
hwc->cq = NULL;
755+
if (hwc->cq)
756+
mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
767757

768758
mana_gd_free_res_map(&hwc->inflight_msg_res);
769759

770760
hwc->num_inflight_msg = 0;
771761

772-
if (hwc->gdma_dev->pdid != INVALID_PDID) {
773-
hwc->gdma_dev->doorbell = INVALID_DOORBELL;
774-
hwc->gdma_dev->pdid = INVALID_PDID;
775-
}
762+
hwc->gdma_dev->doorbell = INVALID_DOORBELL;
763+
hwc->gdma_dev->pdid = INVALID_PDID;
776764

777765
kfree(hwc);
778766
gc->hwc.driver_data = NULL;
779767
gc->hwc.gdma_context = NULL;
768+
769+
vfree(gc->cq_table);
770+
gc->cq_table = NULL;
780771
}
781772

782773
int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len,

0 commit comments

Comments
 (0)