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: Vladislav Zolotarov <vladz@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
a475f603d2
commit
6cbe5065bb
@@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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 @@ load_error3:
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 =
|
||||||
|
Reference in New Issue
Block a user