aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/netpoll.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a01abdd2d3ea..823215d8e90f 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -55,6 +55,7 @@ static void queue_process(struct work_struct *work)
55 struct netpoll_info *npinfo = 55 struct netpoll_info *npinfo =
56 container_of(work, struct netpoll_info, tx_work.work); 56 container_of(work, struct netpoll_info, tx_work.work);
57 struct sk_buff *skb; 57 struct sk_buff *skb;
58 unsigned long flags;
58 59
59 while ((skb = skb_dequeue(&npinfo->txq))) { 60 while ((skb = skb_dequeue(&npinfo->txq))) {
60 struct net_device *dev = skb->dev; 61 struct net_device *dev = skb->dev;
@@ -64,15 +65,19 @@ static void queue_process(struct work_struct *work)
64 continue; 65 continue;
65 } 66 }
66 67
67 netif_tx_lock_bh(dev); 68 local_irq_save(flags);
69 netif_tx_lock(dev);
68 if (netif_queue_stopped(dev) || 70 if (netif_queue_stopped(dev) ||
69 dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) { 71 dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
70 skb_queue_head(&npinfo->txq, skb); 72 skb_queue_head(&npinfo->txq, skb);
71 netif_tx_unlock_bh(dev); 73 netif_tx_unlock(dev);
74 local_irq_restore(flags);
72 75
73 schedule_delayed_work(&npinfo->tx_work, HZ/10); 76 schedule_delayed_work(&npinfo->tx_work, HZ/10);
74 return; 77 return;
75 } 78 }
79 netif_tx_unlock(dev);
80 local_irq_restore(flags);
76 } 81 }
77} 82}
78 83