提交 a29ba9d2 编写于 作者: M Michael Chan 提交者: David S. Miller

bnx2: Free IRQ before freeing status block memory

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: NMichael Chan <mchan@broadcom.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 0438a1b2
......@@ -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;
......@@ -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)
......@@ -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);
}
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册