Commit 2a4e7a085fb44369c450c92cf8bd53b91f874a57

Authored by Mike Ditto
Committed by David S. Miller
1 parent f9c4082df5

forcedeth: Acknowledge only interrupts that are being processed

This is to avoid a race, accidentally acknowledging an interrupt that
we didn't notice and won't immediately process.  This is based solely
on code inspection; it is not known if there was an actual bug here.

Signed-off-by: David Decotigny <david.decotigny@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 8 additions and 5 deletions Side-by-side Diff

drivers/net/ethernet/nvidia/forcedeth.c
... ... @@ -3398,7 +3398,8 @@
3398 3398  
3399 3399 for (i = 0;; i++) {
3400 3400 events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL;
3401   - writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus);
  3401 + writel(events, base + NvRegMSIXIrqStatus);
  3402 + netdev_dbg(dev, "tx irq events: %08x\n", events);
3402 3403 if (!(events & np->irqmask))
3403 3404 break;
3404 3405  
... ... @@ -3509,7 +3510,8 @@
3509 3510  
3510 3511 for (i = 0;; i++) {
3511 3512 events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL;
3512   - writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
  3513 + writel(events, base + NvRegMSIXIrqStatus);
  3514 + netdev_dbg(dev, "rx irq events: %08x\n", events);
3513 3515 if (!(events & np->irqmask))
3514 3516 break;
3515 3517  
... ... @@ -3553,7 +3555,8 @@
3553 3555  
3554 3556 for (i = 0;; i++) {
3555 3557 events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER;
3556   - writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus);
  3558 + writel(events, base + NvRegMSIXIrqStatus);
  3559 + netdev_dbg(dev, "irq events: %08x\n", events);
3557 3560 if (!(events & np->irqmask))
3558 3561 break;
3559 3562  
3560 3563  
... ... @@ -3617,10 +3620,10 @@
3617 3620  
3618 3621 if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
3619 3622 events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
3620   - writel(NVREG_IRQ_TIMER, base + NvRegIrqStatus);
  3623 + writel(events & NVREG_IRQ_TIMER, base + NvRegIrqStatus);
3621 3624 } else {
3622 3625 events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
3623   - writel(NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus);
  3626 + writel(events & NVREG_IRQ_TIMER, base + NvRegMSIXIrqStatus);
3624 3627 }
3625 3628 pci_push(base);
3626 3629 if (!(events & NVREG_IRQ_TIMER))