Skip to content

Commit

Permalink
forcedeth: fix irq clearing and napi spin lock changes
Browse files Browse the repository at this point in the history
This patch clears the irqstatus register with the exact same events it
has read from it. Since the read-write operation is not atomic, a new
irqstatus bit could have been set in between these operations and would
then be cleared accidentally.

Secondly, we now don't need any spin lock protection when
scheduling/completing napi poll as the isr will not execute anymore (as
we turn off all interrupts now).

Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ayaz Abdulla authored and David S. Miller committed Mar 10, 2009
1 parent 6cef67a commit 1b2bb76
Showing 1 changed file with 4 additions and 14 deletions.
18 changes: 4 additions & 14 deletions drivers/net/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -3464,10 +3464,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data)

if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
np->events = readl(base + NvRegIrqStatus);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
writel(np->events, base + NvRegIrqStatus);
} else {
np->events = readl(base + NvRegMSIXIrqStatus);
writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
writel(np->events, base + NvRegMSIXIrqStatus);
}
dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
if (!(np->events & np->irqmask))
Expand All @@ -3476,15 +3476,12 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
nv_msi_workaround(np);

#ifdef CONFIG_FORCEDETH_NAPI
spin_lock(&np->lock);
napi_schedule(&np->napi);

/* Disable furthur irq's
(msix not enabled with napi) */
writel(0, base + NvRegIrqMask);

spin_unlock(&np->lock);

#else
do
{
Expand Down Expand Up @@ -3568,10 +3565,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)

if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
np->events = readl(base + NvRegIrqStatus);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
writel(np->events, base + NvRegIrqStatus);
} else {
np->events = readl(base + NvRegMSIXIrqStatus);
writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
writel(np->events, base + NvRegMSIXIrqStatus);
}
dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
if (!(np->events & np->irqmask))
Expand All @@ -3580,15 +3577,12 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
nv_msi_workaround(np);

#ifdef CONFIG_FORCEDETH_NAPI
spin_lock(&np->lock);
napi_schedule(&np->napi);

/* Disable furthur irq's
(msix not enabled with napi) */
writel(0, base + NvRegIrqMask);

spin_unlock(&np->lock);

#else
do
{
Expand Down Expand Up @@ -3758,13 +3752,9 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
if (rx_work < budget) {
/* re-enable interrupts
(msix not enabled in napi) */
spin_lock_irqsave(&np->lock, flags);

__napi_complete(napi);

writel(np->irqmask, base + NvRegIrqMask);

spin_unlock_irqrestore(&np->lock, flags);
}
return rx_work;
}
Expand Down

0 comments on commit 1b2bb76

Please sign in to comment.