aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-12-12 11:20:42 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-12 11:37:51 -0500
commit3640543df26fd38f31f0c6decc35c07be2a6307c (patch)
tree2d14a4e4bd5d36a2b123656a9793656088437723
parentd224a93d91610fc641fbc5b234b32fcb84045a30 (diff)
[PATCH] netpoll: fix netpoll lockup
current -git doesnt boot on my laptop due to netpoll not unlocking the tx lock in the else branch. booted this up on my laptop with lockdep enabled and there are no locking complaints and it works fine. Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-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