Hi Peter, Peter wrote on 11/13/2007 11:14:50 PM: > @@ -134,7 +134,7 @@ static inline int qdisc_restart(struct net_device *dev) > { > struct Qdisc *q = dev->qdisc; > struct sk_buff *skb; > - int ret; > + int ret = NETDEV_TX_BUSY; > > /* Dequeue packet */ > if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL)) > @@ -145,7 +145,8 @@ static inline int qdisc_restart(struct net_device *dev) > spin_unlock(&dev->queue_lock); > > HARD_TX_LOCK(dev, smp_processor_id()); > - ret = dev_hard_start_xmit(skb, dev); > + if (!netif_subqueue_stopped(dev, skb)) > + ret = dev_hard_start_xmit(skb, dev); > HARD_TX_UNLOCK(dev);
You could optimize this by getting HARD_TX_LOCK after the check. I assume that netif_stop_subqueue (from another CPU) would always be called by the driver xmit, and that is not possible since we hold the __LINK_STATE_QDISC_RUNNING bit. Does that sound correct? PATCH ------ diff -ruNp 1/net/sched/sch_generic.c 2/net/sched/sch_generic.c --- 1/net/sched/sch_generic.c 2007-11-14 11:14:10.000000000 +0530 +++ 2/net/sched/sch_generic.c 2007-11-14 11:18:27.000000000 +0530 @@ -144,10 +144,11 @@ static inline int qdisc_restart(struct n /* And release queue */ spin_unlock(&dev->queue_lock); - HARD_TX_LOCK(dev, smp_processor_id()); if (!netif_subqueue_stopped(dev, skb)) + HARD_TX_LOCK(dev, smp_processor_id()); ret = dev_hard_start_xmit(skb, dev); - HARD_TX_UNLOCK(dev); + HARD_TX_UNLOCK(dev); + } spin_lock(&dev->queue_lock); q = dev->qdisc; Thanks, - KK - 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