Skip to content

Commit

Permalink
bnx2: Free IRQ before freeing status block memory
Browse files Browse the repository at this point in the history
When changing ring size, we free all memory including status block
memory.  If we're in INTA mode and sharing IRQ, the IRQ handler can
be called and it will reference the NULL status block pointer.

Because of the lockless design of the IRQ handler, there is no simple
way to synchronize and prevent this.  So we avoid this problem by
freeing the IRQ handler before freeing the status block memory.

Signed-off-by: Michael Chan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Michael Chan authored and davem330 committed Dec 31, 2010
1 parent 0438a1b commit a29ba9d
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -6096,7 +6096,7 @@ bnx2_request_irq(struct bnx2 *bp)
}

static void
bnx2_free_irq(struct bnx2 *bp)
__bnx2_free_irq(struct bnx2 *bp)
{
struct bnx2_irq *irq;
int i;
Expand All @@ -6107,6 +6107,13 @@ bnx2_free_irq(struct bnx2 *bp)
free_irq(irq->vector, &bp->bnx2_napi[i]);
irq->requested = 0;
}
}

static void
bnx2_free_irq(struct bnx2 *bp)
{

__bnx2_free_irq(bp);
if (bp->flags & BNX2_FLAG_USING_MSI)
pci_disable_msi(bp->pdev);
else if (bp->flags & BNX2_FLAG_USING_MSIX)
Expand Down Expand Up @@ -7092,6 +7099,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)

bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
__bnx2_free_irq(bp);
bnx2_free_skbs(bp);
bnx2_free_mem(bp);
}
Expand All @@ -7103,6 +7111,9 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
int rc;

rc = bnx2_alloc_mem(bp);
if (!rc)
rc = bnx2_request_irq(bp);

if (!rc)
rc = bnx2_init_nic(bp, 0);

Expand Down

0 comments on commit a29ba9d

Please sign in to comment.