From: Stephen Hemminger Date: Tue, 27 Feb 2007 01:18:37 +0000 (-0800) Subject: sky2: transmit timeout deadlock X-Git-Tag: v2.6.19.6~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fead18b0e8a8ffc873482dee0e616d4d0d9592a6;p=thirdparty%2Fkernel%2Fstable.git sky2: transmit timeout deadlock The code in transmit timeout incorrectly assumed that netif_tx_lock was not set. Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 50d60d200af5f..ea11d510c4d7a 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1783,6 +1783,7 @@ out: /* Transmit timeout is only called if we are running, carries is up * and tx queue is full (stopped). + * Called with netif_tx_lock held. */ static void sky2_tx_timeout(struct net_device *dev) { @@ -1808,17 +1809,14 @@ static void sky2_tx_timeout(struct net_device *dev) sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); } else if (report != sky2->tx_cons) { printk(KERN_INFO PFX "status report lost?\n"); - - netif_tx_lock_bh(dev); sky2_tx_complete(sky2, report); - netif_tx_unlock_bh(dev); } else { printk(KERN_INFO PFX "hardware hung? flushing\n"); sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP); sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); - sky2_tx_clean(dev); + sky2_tx_complete(sky2, sky2->tx_prod); sky2_qset(hw, txq); sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);