drivers/net: fixed drivers that support netpoll use ndo_start_xmit()

The NETPOLL API requires that interrupts remain disabled in
netpoll_send_skb(). The use of spin_lock_irq() and spin_unlock_irq()
in the NETPOLL API callbacks causes the interrupts to get enabled and
can lead to kernel instability.

The solution is to use spin_lock_irqsave() and spin_unlock_restore()
to prevent the irqs from getting enabled while in netpoll_send_skb().

Call trace:
netpoll_send_skb()
{
   -> local_irq_save(flags)
     ---> dev->ndo_start_xmit(skb, dev)
         ---> spin_lock_irq()
         ---> spin_unlock_irq() *******here would enable the interrupt.
              ...
   -> local_irq_restore(flags)
}

Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Acked-by: Bruce Ashfield <bruce.ashfield@windriver.com>
Acked-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Dongdong Deng
2009-08-13 19:12:31 +00:00
committed by David S. Miller
parent 0527a1a844
commit 22580f894a
4 changed files with 12 additions and 8 deletions

View File

@@ -652,8 +652,9 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
int entry;
u32 flag;
dma_addr_t mapping;
unsigned long flags;
spin_lock_irq(&tp->lock);
spin_lock_irqsave(&tp->lock, flags);
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % TX_RING_SIZE;
@@ -688,7 +689,7 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Trigger an immediate transmit demand. */
iowrite32(0, tp->base_addr + CSR1);
spin_unlock_irq(&tp->lock);
spin_unlock_irqrestore(&tp->lock, flags);
dev->trans_start = jiffies;