Commit 6cbe5065 authored by Vladislav Zolotarov's avatar Vladislav Zolotarov Committed by David S. Miller

bnx2x: Properly release allocated MSI-X/MSI vectors

Bug fix: Properly release allocated MSI-X/MSI vectors if ifup failed
due to lack of memory.
Signed-off-by: default avatarVladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a475f603
...@@ -6938,19 +6938,21 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) ...@@ -6938,19 +6938,21 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
} }
} }
static void bnx2x_free_irq(struct bnx2x *bp) static void bnx2x_free_irq(struct bnx2x *bp, bool disable_only)
{ {
if (bp->flags & USING_MSIX_FLAG) { if (bp->flags & USING_MSIX_FLAG) {
bnx2x_free_msix_irqs(bp); if (!disable_only)
bnx2x_free_msix_irqs(bp);
pci_disable_msix(bp->pdev); pci_disable_msix(bp->pdev);
bp->flags &= ~USING_MSIX_FLAG; bp->flags &= ~USING_MSIX_FLAG;
} else if (bp->flags & USING_MSI_FLAG) { } else if (bp->flags & USING_MSI_FLAG) {
free_irq(bp->pdev->irq, bp->dev); if (!disable_only)
free_irq(bp->pdev->irq, bp->dev);
pci_disable_msi(bp->pdev); pci_disable_msi(bp->pdev);
bp->flags &= ~USING_MSI_FLAG; bp->flags &= ~USING_MSI_FLAG;
} else } else if (!disable_only)
free_irq(bp->pdev->irq, bp->dev); free_irq(bp->pdev->irq, bp->dev);
} }
...@@ -7443,8 +7445,10 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -7443,8 +7445,10 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
rc = bnx2x_set_num_queues(bp); rc = bnx2x_set_num_queues(bp);
if (bnx2x_alloc_mem(bp)) if (bnx2x_alloc_mem(bp)) {
bnx2x_free_irq(bp, true);
return -ENOMEM; return -ENOMEM;
}
for_each_queue(bp, i) for_each_queue(bp, i)
bnx2x_fp(bp, i, disable_tpa) = bnx2x_fp(bp, i, disable_tpa) =
...@@ -7459,7 +7463,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -7459,7 +7463,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (bp->flags & USING_MSIX_FLAG) { if (bp->flags & USING_MSIX_FLAG) {
rc = bnx2x_req_msix_irqs(bp); rc = bnx2x_req_msix_irqs(bp);
if (rc) { if (rc) {
pci_disable_msix(bp->pdev); bnx2x_free_irq(bp, true);
goto load_error1; goto load_error1;
} }
} else { } else {
...@@ -7471,8 +7475,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -7471,8 +7475,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
rc = bnx2x_req_irq(bp); rc = bnx2x_req_irq(bp);
if (rc) { if (rc) {
BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
if (bp->flags & USING_MSI_FLAG) bnx2x_free_irq(bp, true);
pci_disable_msi(bp->pdev);
goto load_error1; goto load_error1;
} }
if (bp->flags & USING_MSI_FLAG) { if (bp->flags & USING_MSI_FLAG) {
...@@ -7664,7 +7667,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) ...@@ -7664,7 +7667,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
load_error2: load_error2:
/* Release IRQs */ /* Release IRQs */
bnx2x_free_irq(bp); bnx2x_free_irq(bp, false);
load_error1: load_error1:
bnx2x_napi_disable(bp); bnx2x_napi_disable(bp);
for_each_queue(bp, i) for_each_queue(bp, i)
...@@ -7855,7 +7858,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) ...@@ -7855,7 +7858,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bnx2x_stats_handle(bp, STATS_EVENT_STOP); bnx2x_stats_handle(bp, STATS_EVENT_STOP);
/* Release IRQs */ /* Release IRQs */
bnx2x_free_irq(bp); bnx2x_free_irq(bp, false);
/* Wait until tx fastpath tasks complete */ /* Wait until tx fastpath tasks complete */
for_each_queue(bp, i) { for_each_queue(bp, i) {
...@@ -12299,7 +12302,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) ...@@ -12299,7 +12302,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
/* Release IRQs */ /* Release IRQs */
bnx2x_free_irq(bp); bnx2x_free_irq(bp, false);
if (CHIP_IS_E1(bp)) { if (CHIP_IS_E1(bp)) {
struct mac_configuration_cmd *config = struct mac_configuration_cmd *config =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment