Skip to content

Commit

Permalink
[NETPOLL]: tx lock deadlock fix
Browse files Browse the repository at this point in the history
If sky2 device poll routine is called from netpoll_send_skb, it would
deadlock. The netpoll_send_skb held the netif_tx_lock, and the poll
routine could acquire it to clean up skb's. Other drivers might use
same locking model.

The driver is correct, netpoll should not introduce more locking
problems than it causes already. So change the code to drop lock
before calling poll handler.

Signed-off-by: Stephen Hemminger <shemminger@linux.foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jun 27, 2007
1 parent 48d8d7e commit 0db3dc7
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions net/core/netpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,22 +250,23 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
unsigned long flags;

local_irq_save(flags);
if (netif_tx_trylock(dev)) {
/* try until next clock tick */
for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
tries > 0; --tries) {
/* try until next clock tick */
for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
tries > 0; --tries) {
if (netif_tx_trylock(dev)) {
if (!netif_queue_stopped(dev))
status = dev->hard_start_xmit(skb, dev);
netif_tx_unlock(dev);

if (status == NETDEV_TX_OK)
break;

/* tickle device maybe there is some cleanup */
netpoll_poll(np);

udelay(USEC_PER_POLL);
}
netif_tx_unlock(dev);

/* tickle device maybe there is some cleanup */
netpoll_poll(np);

udelay(USEC_PER_POLL);
}
local_irq_restore(flags);
}
Expand Down

0 comments on commit 0db3dc7

Please sign in to comment.