Commit 3640543d authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[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: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d224a93d
...@@ -55,6 +55,7 @@ static void queue_process(struct work_struct *work) ...@@ -55,6 +55,7 @@ static void queue_process(struct work_struct *work)
struct netpoll_info *npinfo = struct netpoll_info *npinfo =
container_of(work, struct netpoll_info, tx_work.work); container_of(work, struct netpoll_info, tx_work.work);
struct sk_buff *skb; struct sk_buff *skb;
unsigned long flags;
while ((skb = skb_dequeue(&npinfo->txq))) { while ((skb = skb_dequeue(&npinfo->txq))) {
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
...@@ -64,15 +65,19 @@ static void queue_process(struct work_struct *work) ...@@ -64,15 +65,19 @@ static void queue_process(struct work_struct *work)
continue; continue;
} }
netif_tx_lock_bh(dev); local_irq_save(flags);
netif_tx_lock(dev);
if (netif_queue_stopped(dev) || if (netif_queue_stopped(dev) ||
dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) { dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
skb_queue_head(&npinfo->txq, skb); skb_queue_head(&npinfo->txq, skb);
netif_tx_unlock_bh(dev); netif_tx_unlock(dev);
local_irq_restore(flags);
schedule_delayed_work(&npinfo->tx_work, HZ/10); schedule_delayed_work(&npinfo->tx_work, HZ/10);
return; return;
} }
netif_tx_unlock(dev);
local_irq_restore(flags);
} }
} }
......
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