Commit e8106b94 authored by Arjan van de Ven's avatar Arjan van de Ven Committed by Linus Torvalds

[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: default avatarArjan van de Ven <arjan@linux.intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 6ea36ddb
...@@ -299,7 +299,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -299,7 +299,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
* Slow phase with lock held. * 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); spin_lock(&ei_local->page_lock);
...@@ -338,7 +338,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -338,7 +338,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
outb_p(ENISR_ALL, e8390_base + EN0_IMR); outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock(&ei_local->page_lock); spin_unlock(&ei_local->page_lock);
enable_irq_lockdep(dev->irq); enable_irq_lockdep_irqrestore(dev->irq, &flags);
ei_local->stat.tx_errors++; ei_local->stat.tx_errors++;
return 1; return 1;
} }
...@@ -379,7 +379,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -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); outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock(&ei_local->page_lock); spin_unlock(&ei_local->page_lock);
enable_irq_lockdep(dev->irq); enable_irq_lockdep_irqrestore(dev->irq, &flags);
dev_kfree_skb (skb); dev_kfree_skb (skb);
ei_local->stat.tx_bytes += send_length; ei_local->stat.tx_bytes += send_length;
......
...@@ -123,6 +123,14 @@ static inline void disable_irq_nosync_lockdep(unsigned int irq) ...@@ -123,6 +123,14 @@ static inline void disable_irq_nosync_lockdep(unsigned int irq)
#endif #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) static inline void disable_irq_lockdep(unsigned int irq)
{ {
disable_irq(irq); disable_irq(irq);
...@@ -139,6 +147,14 @@ static inline void enable_irq_lockdep(unsigned int irq) ...@@ -139,6 +147,14 @@ static inline void enable_irq_lockdep(unsigned int irq)
enable_irq(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: */ /* IRQ wakeup (PM) control: */
extern int set_irq_wake(unsigned int irq, unsigned int on); extern int set_irq_wake(unsigned int irq, unsigned int on);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment