aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/net/pkt_sched.h4
-rw-r--r--include/net/sch_generic.h6
-rw-r--r--net/sched/sch_generic.c18
4 files changed, 19 insertions, 10 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0883fcf2d16a..9240a95793be 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -441,7 +441,6 @@ static inline void napi_synchronize(const struct napi_struct *n)
441enum netdev_queue_state_t 441enum netdev_queue_state_t
442{ 442{
443 __QUEUE_STATE_XOFF, 443 __QUEUE_STATE_XOFF,
444 __QUEUE_STATE_QDISC_RUNNING,
445}; 444};
446 445
447struct netdev_queue { 446struct netdev_queue {
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index cb9527815606..06a442d85186 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -88,8 +88,10 @@ extern void __qdisc_run(struct netdev_queue *txq);
88 88
89static inline void qdisc_run(struct netdev_queue *txq) 89static inline void qdisc_run(struct netdev_queue *txq)
90{ 90{
91 struct Qdisc *q = txq->qdisc;
92
91 if (!netif_tx_queue_stopped(txq) && 93 if (!netif_tx_queue_stopped(txq) &&
92 !test_and_set_bit(__QUEUE_STATE_QDISC_RUNNING, &txq->state)) 94 !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
93 __qdisc_run(txq); 95 __qdisc_run(txq);
94} 96}
95 97
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index b96c3d9e10a8..bc2a09da21b1 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -23,6 +23,11 @@ struct qdisc_rate_table
23 int refcnt; 23 int refcnt;
24}; 24};
25 25
26enum qdisc_state_t
27{
28 __QDISC_STATE_RUNNING,
29};
30
26struct Qdisc 31struct Qdisc
27{ 32{
28 int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev); 33 int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
@@ -36,6 +41,7 @@ struct Qdisc
36 u32 handle; 41 u32 handle;
37 u32 parent; 42 u32 parent;
38 atomic_t refcnt; 43 atomic_t refcnt;
44 unsigned long state;
39 struct sk_buff *gso_skb; 45 struct sk_buff *gso_skb;
40 struct sk_buff_head q; 46 struct sk_buff_head q;
41 struct netdev_queue *dev_queue; 47 struct netdev_queue *dev_queue;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 2bd75befa066..ac208c2b2d10 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -130,8 +130,8 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb,
130/* 130/*
131 * NOTE: Called under queue->lock with locally disabled BH. 131 * NOTE: Called under queue->lock with locally disabled BH.
132 * 132 *
133 * __QUEUE_STATE_QDISC_RUNNING guarantees only one CPU can process 133 * __QDISC_STATE_RUNNING guarantees only one CPU can process
134 * this queue at a time. queue->lock serializes queue accesses for 134 * this qdisc at a time. queue->lock serializes queue accesses for
135 * this queue AND txq->qdisc pointer itself. 135 * this queue AND txq->qdisc pointer itself.
136 * 136 *
137 * netif_tx_lock serializes accesses to device driver. 137 * netif_tx_lock serializes accesses to device driver.
@@ -146,9 +146,9 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb,
146 * >0 - queue is not empty. 146 * >0 - queue is not empty.
147 * 147 *
148 */ 148 */
149static inline int qdisc_restart(struct netdev_queue *txq) 149static inline int qdisc_restart(struct netdev_queue *txq,
150 struct Qdisc *q)
150{ 151{
151 struct Qdisc *q = txq->qdisc;
152 int ret = NETDEV_TX_BUSY; 152 int ret = NETDEV_TX_BUSY;
153 struct net_device *dev; 153 struct net_device *dev;
154 struct sk_buff *skb; 154 struct sk_buff *skb;
@@ -168,7 +168,6 @@ static inline int qdisc_restart(struct netdev_queue *txq)
168 HARD_TX_UNLOCK(dev, txq); 168 HARD_TX_UNLOCK(dev, txq);
169 169
170 spin_lock(&txq->lock); 170 spin_lock(&txq->lock);
171 q = txq->qdisc;
172 171
173 switch (ret) { 172 switch (ret) {
174 case NETDEV_TX_OK: 173 case NETDEV_TX_OK:
@@ -197,8 +196,9 @@ static inline int qdisc_restart(struct netdev_queue *txq)
197void __qdisc_run(struct netdev_queue *txq) 196void __qdisc_run(struct netdev_queue *txq)
198{ 197{
199 unsigned long start_time = jiffies; 198 unsigned long start_time = jiffies;
199 struct Qdisc *q = txq->qdisc;
200 200
201 while (qdisc_restart(txq)) { 201 while (qdisc_restart(txq, q)) {
202 if (netif_tx_queue_stopped(txq)) 202 if (netif_tx_queue_stopped(txq))
203 break; 203 break;
204 204
@@ -213,7 +213,7 @@ void __qdisc_run(struct netdev_queue *txq)
213 } 213 }
214 } 214 }
215 215
216 clear_bit(__QUEUE_STATE_QDISC_RUNNING, &txq->state); 216 clear_bit(__QDISC_STATE_RUNNING, &q->state);
217} 217}
218 218
219static void dev_watchdog(unsigned long arg) 219static void dev_watchdog(unsigned long arg)
@@ -666,14 +666,16 @@ static bool some_qdisc_is_running(struct net_device *dev, int lock)
666 666
667 for (i = 0; i < dev->num_tx_queues; i++) { 667 for (i = 0; i < dev->num_tx_queues; i++) {
668 struct netdev_queue *dev_queue; 668 struct netdev_queue *dev_queue;
669 struct Qdisc *q;
669 int val; 670 int val;
670 671
671 dev_queue = netdev_get_tx_queue(dev, i); 672 dev_queue = netdev_get_tx_queue(dev, i);
673 q = dev_queue->qdisc;
672 674
673 if (lock) 675 if (lock)
674 spin_lock_bh(&dev_queue->lock); 676 spin_lock_bh(&dev_queue->lock);
675 677
676 val = test_bit(__QUEUE_STATE_QDISC_RUNNING, &dev_queue->state); 678 val = test_bit(__QDISC_STATE_RUNNING, &q->state);
677 679
678 if (lock) 680 if (lock)
679 spin_unlock_bh(&dev_queue->lock); 681 spin_unlock_bh(&dev_queue->lock);