[PATCH] mv643xx_eth: Fix tx_timeout to only conditionally wake tx queue
After resetting the hardware on a tx_timeout, call netif_wake_queue() only if we have free tx descriptors. Also, attempt to recover if mv643xx_eth_start_xmit() is called when there are fewer free tx descriptors than expected. The BUG_ON() call we are replacing was hit on a tx_timeout that called netif_wake_queue(), indirectly via netif_device_attach(), even though we did not have enough free tx descriptors. Signed-off-by: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
committed by
Jeff Garzik
parent
5c53740877
commit
94843566d7
@@ -281,10 +281,16 @@ static void mv643xx_eth_tx_timeout_task(struct net_device *dev)
|
|||||||
{
|
{
|
||||||
struct mv643xx_private *mp = netdev_priv(dev);
|
struct mv643xx_private *mp = netdev_priv(dev);
|
||||||
|
|
||||||
netif_device_detach(dev);
|
if (!netif_running(dev))
|
||||||
|
return;
|
||||||
|
|
||||||
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
eth_port_reset(mp->port_num);
|
eth_port_reset(mp->port_num);
|
||||||
eth_port_start(dev);
|
eth_port_start(dev);
|
||||||
netif_device_attach(dev);
|
|
||||||
|
if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB)
|
||||||
|
netif_wake_queue(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1186,7 +1192,12 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
|
|
||||||
BUG_ON(netif_queue_stopped(dev));
|
BUG_ON(netif_queue_stopped(dev));
|
||||||
BUG_ON(skb == NULL);
|
BUG_ON(skb == NULL);
|
||||||
BUG_ON(mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB);
|
|
||||||
|
if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) {
|
||||||
|
printk(KERN_ERR "%s: transmit with queue full\n", dev->name);
|
||||||
|
netif_stop_queue(dev);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (has_tiny_unaligned_frags(skb)) {
|
if (has_tiny_unaligned_frags(skb)) {
|
||||||
if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
|
if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
|
||||||
|
Reference in New Issue
Block a user