[PATCH] lockdep: core, add enable/disable_irq_irqsave/irqrestore() APIs
authorArjan van de Ven <arjan@linux.intel.com>
Fri, 29 Sep 2006 09:01:08 +0000 (02:01 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 29 Sep 2006 16:18:20 +0000 (09:18 -0700)
Introduce the disable_irq_nosync_lockdep_irqsave() and
enable_irq_lockdep_irqrestore() APIs.  These are needed for NE2000; basically
NE2000 calls disable_irq and enable_irq as locking against the IRQ handler,
but both in cases where interrupts are on and off.  This means that lockdep
needs to track the old state of the virtual irq flags on disable_irq, and
restore these at enable_irq time.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/net/8390.c
include/linux/interrupt.h

index 5b6b05ed8f3c90553d5b9d710e39d4da54edb74d..9d34056147ad5c4c026b74e58a59ffc99cb1ec62 100644 (file)
@@ -299,7 +299,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
         *      Slow phase with lock held.
         */
 
-       disable_irq_nosync_lockdep(dev->irq);
+       disable_irq_nosync_lockdep_irqsave(dev->irq, &flags);
 
        spin_lock(&ei_local->page_lock);
 
@@ -338,7 +338,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
                outb_p(ENISR_ALL, e8390_base + EN0_IMR);
                spin_unlock(&ei_local->page_lock);
-               enable_irq_lockdep(dev->irq);
+               enable_irq_lockdep_irqrestore(dev->irq, &flags);
                ei_local->stat.tx_errors++;
                return 1;
        }
@@ -379,7 +379,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
        outb_p(ENISR_ALL, e8390_base + EN0_IMR);
 
        spin_unlock(&ei_local->page_lock);
-       enable_irq_lockdep(dev->irq);
+       enable_irq_lockdep_irqrestore(dev->irq, &flags);
 
        dev_kfree_skb (skb);
        ei_local->stat.tx_bytes += send_length;
index d5afee95fd435294f2ee894cd75a31b7cc96be7b..1f97e3d92639e75aaed86a8066518e2526fa1dee 100644 (file)
@@ -123,6 +123,14 @@ static inline void disable_irq_nosync_lockdep(unsigned int irq)
 #endif
 }
 
+static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
+{
+       disable_irq_nosync(irq);
+#ifdef CONFIG_LOCKDEP
+       local_irq_save(*flags);
+#endif
+}
+
 static inline void disable_irq_lockdep(unsigned int irq)
 {
        disable_irq(irq);
@@ -139,6 +147,14 @@ static inline void enable_irq_lockdep(unsigned int irq)
        enable_irq(irq);
 }
 
+static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
+{
+#ifdef CONFIG_LOCKDEP
+       local_irq_restore(*flags);
+#endif
+       enable_irq(irq);
+}
+
 /* IRQ wakeup (PM) control: */
 extern int set_irq_wake(unsigned int irq, unsigned int on);