[PATCH] skge: irq lock race
authorStephen Hemminger <shemminger@osdl.org>
Fri, 1 Sep 2006 22:53:48 +0000 (15:53 -0700)
committerJeff Garzik <jeff@garzik.org>
Wed, 6 Sep 2006 15:19:23 +0000 (11:19 -0400)
The driver needs to access the IRQ status inside of lock to avoid
races with other places changing IRQ mask etc. This may be related
to some of the SMP bugs reported against skge in kernel bugzilla.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/skge.c

index e86a88aa9d066d44ca5d8f414b103f49ea953a11..8a321be24835a96ad4e85cc810ffce1805c1fc11 100644 (file)
@@ -2891,13 +2891,15 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct skge_hw *hw = dev_id;
        u32 status;
+       int handled = 0;
 
+       spin_lock(&hw->hw_lock);
        /* Reading this register masks IRQ */
        status = skge_read32(hw, B0_SP_ISRC);
        if (status == 0)
-               return IRQ_NONE;
+               goto out;
 
-       spin_lock(&hw->hw_lock);
+       handled = 1;
        status &= hw->intr_mask;
        if (status & IS_EXT_REG) {
                hw->intr_mask &= ~IS_EXT_REG;
@@ -2959,9 +2961,10 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
 
        skge_write32(hw, B0_IMSK, hw->intr_mask);
        skge_read32(hw, B0_IMSK);
+out:
        spin_unlock(&hw->hw_lock);
 
-       return IRQ_HANDLED;
+       return IRQ_RETVAL(handled);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER