Commit e8106b941ceab68cc5ff713df7b1276484554584

Authored by Arjan van de Ven
Committed by Linus Torvalds
1 parent 6ea36ddbd1

[PATCH] lockdep: core, add enable/disable_irq_irqsave/irqrestore() APIs

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>

Showing 2 changed files with 19 additions and 3 deletions Side-by-side Diff

... ... @@ -299,7 +299,7 @@
299 299 * Slow phase with lock held.
300 300 */
301 301  
302   - disable_irq_nosync_lockdep(dev->irq);
  302 + disable_irq_nosync_lockdep_irqsave(dev->irq, &flags);
303 303  
304 304 spin_lock(&ei_local->page_lock);
305 305  
... ... @@ -338,7 +338,7 @@
338 338 netif_stop_queue(dev);
339 339 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
340 340 spin_unlock(&ei_local->page_lock);
341   - enable_irq_lockdep(dev->irq);
  341 + enable_irq_lockdep_irqrestore(dev->irq, &flags);
342 342 ei_local->stat.tx_errors++;
343 343 return 1;
344 344 }
... ... @@ -379,7 +379,7 @@
379 379 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
380 380  
381 381 spin_unlock(&ei_local->page_lock);
382   - enable_irq_lockdep(dev->irq);
  382 + enable_irq_lockdep_irqrestore(dev->irq, &flags);
383 383  
384 384 dev_kfree_skb (skb);
385 385 ei_local->stat.tx_bytes += send_length;
include/linux/interrupt.h
... ... @@ -123,6 +123,14 @@
123 123 #endif
124 124 }
125 125  
  126 +static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
  127 +{
  128 + disable_irq_nosync(irq);
  129 +#ifdef CONFIG_LOCKDEP
  130 + local_irq_save(*flags);
  131 +#endif
  132 +}
  133 +
126 134 static inline void disable_irq_lockdep(unsigned int irq)
127 135 {
128 136 disable_irq(irq);
... ... @@ -135,6 +143,14 @@
135 143 {
136 144 #ifdef CONFIG_LOCKDEP
137 145 local_irq_enable();
  146 +#endif
  147 + enable_irq(irq);
  148 +}
  149 +
  150 +static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
  151 +{
  152 +#ifdef CONFIG_LOCKDEP
  153 + local_irq_restore(*flags);
138 154 #endif
139 155 enable_irq(irq);
140 156 }