aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-03-16 17:01:26 -0400
committerJeff Garzik <jeff@garzik.org>2007-03-23 01:48:33 -0400
commite3a1b99fb60dab1b39d5022d1d8f47bebfe6d8c6 (patch)
tree3cacd444ae5b08ad30dd9cf1facbaf41d315913c /drivers
parent12998096cc48563a04ca751965ba17c3f73a5461 (diff)
skge: deadlock on tx timeout
The skge driver will deadlock if gets a transmit timeout because the netif_tx_lock() is already held. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/skge.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 8fecf1b817f7..fad189e01ec6 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2576,7 +2576,11 @@ static int skge_down(struct net_device *dev)
2576 skge_led(skge, LED_MODE_OFF); 2576 skge_led(skge, LED_MODE_OFF);
2577 2577
2578 netif_poll_disable(dev); 2578 netif_poll_disable(dev);
2579
2580 netif_tx_lock_bh(dev);
2579 skge_tx_clean(dev); 2581 skge_tx_clean(dev);
2582 netif_tx_unlock_bh(dev);
2583
2580 skge_rx_clean(skge); 2584 skge_rx_clean(skge);
2581 2585
2582 kfree(skge->rx_ring.start); 2586 kfree(skge->rx_ring.start);
@@ -2721,7 +2725,6 @@ static void skge_tx_clean(struct net_device *dev)
2721 struct skge_port *skge = netdev_priv(dev); 2725 struct skge_port *skge = netdev_priv(dev);
2722 struct skge_element *e; 2726 struct skge_element *e;
2723 2727
2724 netif_tx_lock_bh(dev);
2725 for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) { 2728 for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
2726 struct skge_tx_desc *td = e->desc; 2729 struct skge_tx_desc *td = e->desc;
2727 skge_tx_free(skge, e, td->control); 2730 skge_tx_free(skge, e, td->control);
@@ -2730,7 +2733,6 @@ static void skge_tx_clean(struct net_device *dev)
2730 2733
2731 skge->tx_ring.to_clean = e; 2734 skge->tx_ring.to_clean = e;
2732 netif_wake_queue(dev); 2735 netif_wake_queue(dev);
2733 netif_tx_unlock_bh(dev);
2734} 2736}
2735 2737
2736static void skge_tx_timeout(struct net_device *dev) 2738static void skge_tx_timeout(struct net_device *dev)