From: Ivan Vecera <ivecera@redhat.com> Date: Wed, 8 Dec 2010 18:06:37 -0500 Subject: [net] forcedeth: fix race condition in latest backport Message-id: <1291831597-24982-1-git-send-email-ivecera@redhat.com> Patchwork-id: 30010 O-Subject: [RHEL5.6 PATCH] forcedeth: partially revert commit 1b2bb76 Bugzilla: 658434 RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com> RH-Acked-by: Andy Gospodarek <gospo@redhat.com> BZs: #658434 - forcedeth driver panics while booting debug kernel Description: This patch reverts part of the upstream commit introduced spin lock changes that cause race condition found during testing. This is very strange issue because it is reproducible only on sun-x4440-01.rhts.eng.bos.redhat.com and only with i686 kernel-debug package. Test status: Tested by myself Reverted upstream commit: 1b2bb76 forcedeth: fix irq clearing and napi spin lock changes Signed-off-by: Ivan Vecera <ivecera@redhat.com> diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index f256645..0c5dcf5 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3447,6 +3447,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) nv_msi_workaround(np); + spin_lock(&np->lock); if (netif_rx_schedule_prep(dev)) { /* * Disable further irq's (msix not enabled with napi) @@ -3454,6 +3455,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) writel(0, base + NvRegIrqMask); __netif_rx_schedule(dev); } + spin_unlock(&np->lock); dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name); @@ -3486,6 +3488,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data, struct pt_regs *reg nv_msi_workaround(np); + spin_lock(&np->lock); if (netif_rx_schedule_prep(dev)) { /* * Disable further irq's (msix not enabled with napi) @@ -3493,6 +3496,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data, struct pt_regs *reg writel(0, base + NvRegIrqMask); __netif_rx_schedule(dev); } + spin_unlock(&np->lock); dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name); return IRQ_HANDLED; @@ -3605,9 +3609,15 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) if (rx_work < budget) { /* re-enable interrupts (msix not enabled in napi) */ - napi_complete(napi); + napi_gro_flush(napi); + + spin_lock_irqsave(&np->lock, flags); + + __netif_rx_complete(dev); writel(np->irqmask, base + NvRegIrqMask); + + spin_unlock_irqrestore(&np->lock, flags); } return rx_work; }