aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_generic.c93
1 files changed, 57 insertions, 36 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 27d03816ec3e..693df7ae33d8 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -37,15 +37,11 @@
37 * - updates to tree and tree walking are only done under the rtnl mutex. 37 * - updates to tree and tree walking are only done under the rtnl mutex.
38 */ 38 */
39 39
40static inline int qdisc_qlen(struct Qdisc *q)
41{
42 return q->q.qlen;
43}
44
45static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q) 40static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
46{ 41{
47 q->gso_skb = skb; 42 q->gso_skb = skb;
48 q->qstats.requeues++; 43 q->qstats.requeues++;
44 q->q.qlen++; /* it's still part of the queue */
49 __netif_schedule(q); 45 __netif_schedule(q);
50 46
51 return 0; 47 return 0;
@@ -61,9 +57,11 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
61 57
62 /* check the reason of requeuing without tx lock first */ 58 /* check the reason of requeuing without tx lock first */
63 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); 59 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
64 if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq)) 60 if (!netif_tx_queue_stopped(txq) &&
61 !netif_tx_queue_frozen(txq)) {
65 q->gso_skb = NULL; 62 q->gso_skb = NULL;
66 else 63 q->q.qlen--;
64 } else
67 skb = NULL; 65 skb = NULL;
68 } else { 66 } else {
69 skb = q->dequeue(q); 67 skb = q->dequeue(q);
@@ -103,44 +101,23 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb,
103} 101}
104 102
105/* 103/*
106 * NOTE: Called under qdisc_lock(q) with locally disabled BH. 104 * Transmit one skb, and handle the return status as required. Holding the
107 * 105 * __QDISC_STATE_RUNNING bit guarantees that only one CPU can execute this
108 * __QDISC_STATE_RUNNING guarantees only one CPU can process 106 * function.
109 * this qdisc at a time. qdisc_lock(q) serializes queue accesses for
110 * this queue.
111 *
112 * netif_tx_lock serializes accesses to device driver.
113 *
114 * qdisc_lock(q) and netif_tx_lock are mutually exclusive,
115 * if one is grabbed, another must be free.
116 *
117 * Note, that this procedure can be called by a watchdog timer
118 * 107 *
119 * Returns to the caller: 108 * Returns to the caller:
120 * 0 - queue is empty or throttled. 109 * 0 - queue is empty or throttled.
121 * >0 - queue is not empty. 110 * >0 - queue is not empty.
122 *
123 */ 111 */
124static inline int qdisc_restart(struct Qdisc *q) 112int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
113 struct net_device *dev, struct netdev_queue *txq,
114 spinlock_t *root_lock)
125{ 115{
126 struct netdev_queue *txq;
127 int ret = NETDEV_TX_BUSY; 116 int ret = NETDEV_TX_BUSY;
128 struct net_device *dev;
129 spinlock_t *root_lock;
130 struct sk_buff *skb;
131
132 /* Dequeue packet */
133 if (unlikely((skb = dequeue_skb(q)) == NULL))
134 return 0;
135
136 root_lock = qdisc_lock(q);
137 117
138 /* And release qdisc */ 118 /* And release qdisc */
139 spin_unlock(root_lock); 119 spin_unlock(root_lock);
140 120
141 dev = qdisc_dev(q);
142 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
143
144 HARD_TX_LOCK(dev, txq, smp_processor_id()); 121 HARD_TX_LOCK(dev, txq, smp_processor_id());
145 if (!netif_tx_queue_stopped(txq) && 122 if (!netif_tx_queue_stopped(txq) &&
146 !netif_tx_queue_frozen(txq)) 123 !netif_tx_queue_frozen(txq))
@@ -177,6 +154,44 @@ static inline int qdisc_restart(struct Qdisc *q)
177 return ret; 154 return ret;
178} 155}
179 156
157/*
158 * NOTE: Called under qdisc_lock(q) with locally disabled BH.
159 *
160 * __QDISC_STATE_RUNNING guarantees only one CPU can process
161 * this qdisc at a time. qdisc_lock(q) serializes queue accesses for
162 * this queue.
163 *
164 * netif_tx_lock serializes accesses to device driver.
165 *
166 * qdisc_lock(q) and netif_tx_lock are mutually exclusive,
167 * if one is grabbed, another must be free.
168 *
169 * Note, that this procedure can be called by a watchdog timer
170 *
171 * Returns to the caller:
172 * 0 - queue is empty or throttled.
173 * >0 - queue is not empty.
174 *
175 */
176static inline int qdisc_restart(struct Qdisc *q)
177{
178 struct netdev_queue *txq;
179 struct net_device *dev;
180 spinlock_t *root_lock;
181 struct sk_buff *skb;
182
183 /* Dequeue packet */
184 skb = dequeue_skb(q);
185 if (unlikely(!skb))
186 return 0;
187
188 root_lock = qdisc_lock(q);
189 dev = qdisc_dev(q);
190 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
191
192 return sch_direct_xmit(skb, q, dev, txq, root_lock);
193}
194
180void __qdisc_run(struct Qdisc *q) 195void __qdisc_run(struct Qdisc *q)
181{ 196{
182 unsigned long start_time = jiffies; 197 unsigned long start_time = jiffies;
@@ -547,8 +562,11 @@ void qdisc_reset(struct Qdisc *qdisc)
547 if (ops->reset) 562 if (ops->reset)
548 ops->reset(qdisc); 563 ops->reset(qdisc);
549 564
550 kfree_skb(qdisc->gso_skb); 565 if (qdisc->gso_skb) {
551 qdisc->gso_skb = NULL; 566 kfree_skb(qdisc->gso_skb);
567 qdisc->gso_skb = NULL;
568 qdisc->q.qlen = 0;
569 }
552} 570}
553EXPORT_SYMBOL(qdisc_reset); 571EXPORT_SYMBOL(qdisc_reset);
554 572
@@ -605,6 +623,9 @@ static void attach_one_default_qdisc(struct net_device *dev,
605 printk(KERN_INFO "%s: activation failed\n", dev->name); 623 printk(KERN_INFO "%s: activation failed\n", dev->name);
606 return; 624 return;
607 } 625 }
626
627 /* Can by-pass the queue discipline for default qdisc */
628 qdisc->flags |= TCQ_F_CAN_BYPASS;
608 } else { 629 } else {
609 qdisc = &noqueue_qdisc; 630 qdisc = &noqueue_qdisc;
610 } 631 }