pkt_sched: Add queue stopped test back to qdisc_run().
authorDavid S. Miller <davem@davemloft.net>
Wed, 13 Aug 2008 09:13:34 +0000 (02:13 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 Aug 2008 09:13:34 +0000 (02:13 -0700)
Based upon a bug report by Andrew Gallatin on netdev
with subject "CPU utilization increased in 2.6.27rc"

In commit 37437bb2e1ae8af470dfcd5b4ff454110894ccaf
("pkt_sched: Schedule qdiscs instead of netdev_queue.")
the test of the queue being stopped was erroneously
removed from qdisc_run().

When the TX queue of the device fills up, this omission
causes lots of extraneous useless work to be queued up
to softirq context, where we'll just return immediately
because the device is still stuffed up.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/pkt_sched.h

index 6affcfaa123edda5df7f65275d117063ed00018d..853fe83d9f3700b9179e8a82c794970411ac5c20 100644 (file)
@@ -89,7 +89,10 @@ extern void __qdisc_run(struct Qdisc *q);
 
 static inline void qdisc_run(struct Qdisc *q)
 {
-       if (!test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
+       struct netdev_queue *txq = q->dev_queue;
+
+       if (!netif_tx_queue_stopped(txq) &&
+           !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
                __qdisc_run(q);
 }