diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2008-03-18 11:32:41 -0700 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-16 20:06:48 -0400 |
commit | 4d64e718b46f4eedaf0379e0150de4d28b06b916 (patch) | |
tree | c4611a3fcd3011327dda08e8069bf2df38e21ea0 | |
parent | dd9e0dda66ba38a2ddd1405ac279894260dc5c36 (diff) | |
download | linux-4d64e718b46f4eedaf0379e0150de4d28b06b916.tar.bz2 |
mv643xx_eth: mp->tx_desc_count needs spinlock protection
mv643xx_eth_start_xmit() should check mp->tx_desc_count only
inside the mp->lock spinlock.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Reviewed-by: Tzachi Perelstein <tzachi@marvell.com>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
-rw-r--r-- | drivers/net/mv643xx_eth.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index d65cadef4d22..06e024f5d68b 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1741,23 +1741,22 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) BUG_ON(netif_queue_stopped(dev)); BUG_ON(skb == NULL); + if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) { + stats->tx_dropped++; + printk(KERN_DEBUG "%s: failed to linearize tiny " + "unaligned fragment\n", dev->name); + return 1; + } + + spin_lock_irqsave(&mp->lock, flags); + 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); + spin_unlock_irqrestore(&mp->lock, flags); return 1; } - if (has_tiny_unaligned_frags(skb)) { - if (__skb_linearize(skb)) { - stats->tx_dropped++; - printk(KERN_DEBUG "%s: failed to linearize tiny " - "unaligned fragment\n", dev->name); - return 1; - } - } - - spin_lock_irqsave(&mp->lock, flags); - eth_tx_submit_descs_for_skb(mp, skb); stats->tx_bytes += skb->len; stats->tx_packets++; |