From: Stephen Hemminger <[EMAIL PROTECTED]> Date: Mon, 5 Dec 2005 16:37:53 -0800
> I assert that with lockless transmit (ie NETIF_F_LLTX) it is > possible for two cpu's to race with the transmit flow control > (netif_stop_queue/netif_wake_queue). I see it with sky2, and > probably could reproduce with tg3 as well. > > A. CPU is in middle of building up a transmit, > B. CPU gets packet and passes > netif_queue_stopped test > A. CPU completes transmit and since tx queue is full sets stopped > B. tests for tx queue full and.... > > This will cause the driver to return DEVICE_BUSY > Tg3, skge, sky2 and rionet all print message, that this is a BUG! > but it is just losing a corner case race, and should be silent. I totally agree, but would recommend something like the patch below, using tg3 as an example. We should still warn if the transmit ring is full _and_ netif_stop_queue() is false. That is an illegal state to observe while holding the tx_lock. If netif_stop_queue() is true, then it's just the race you describe above, and should just silently return NETDEV_TX_BUSY, as you recommend. Agreed? diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 1828a6b..d9f65f4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3565,12 +3565,20 @@ static int tg3_start_xmit(struct sk_buff if (!spin_trylock(&tp->tx_lock)) return NETDEV_TX_LOCKED; - /* This is a hard error, log it. */ if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { - netif_stop_queue(dev); + int was_stopped = netif_queue_stopped(dev); + + if (!was_stopped) + netif_stop_queue(dev); + spin_unlock(&tp->tx_lock); - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", - dev->name); + + if (!was_stopped) { + /* This is a hard error, log it. */ + printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " + "queue awake!\n", dev->name); + } + return NETDEV_TX_BUSY; } - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html