aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/act_api.c18
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sched/sch_api.c117
-rw-r--r--net/sched/sch_atm.c14
-rw-r--r--net/sched/sch_cbq.c33
-rw-r--r--net/sched/sch_dsmark.c10
-rw-r--r--net/sched/sch_generic.c86
-rw-r--r--net/sched/sch_hfsc.c12
-rw-r--r--net/sched/sch_htb.c31
-rw-r--r--net/sched/sch_netem.c5
-rw-r--r--net/sched/sch_prio.c18
-rw-r--r--net/sched/sch_red.c2
-rw-r--r--net/sched/sch_sfq.c8
-rw-r--r--net/sched/sch_tbf.c14
-rw-r--r--net/sched/sch_teql.c9
15 files changed, 210 insertions, 169 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index d308c19aa3f9..9974b3f04f05 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -205,10 +205,9 @@ struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind,
205{ 205{
206 struct tcf_common *p = NULL; 206 struct tcf_common *p = NULL;
207 if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) { 207 if (index && (p = tcf_hash_lookup(index, hinfo)) != NULL) {
208 if (bind) { 208 if (bind)
209 p->tcfc_bindcnt++; 209 p->tcfc_bindcnt++;
210 p->tcfc_refcnt++; 210 p->tcfc_refcnt++;
211 }
212 a->priv = p; 211 a->priv = p;
213 } 212 }
214 return p; 213 return p;
@@ -752,7 +751,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
752 struct nlattr *tb[TCA_ACT_MAX+1]; 751 struct nlattr *tb[TCA_ACT_MAX+1];
753 struct nlattr *kind; 752 struct nlattr *kind;
754 struct tc_action *a = create_a(0); 753 struct tc_action *a = create_a(0);
755 int err = -EINVAL; 754 int err = -ENOMEM;
756 755
757 if (a == NULL) { 756 if (a == NULL) {
758 printk("tca_action_flush: couldnt create tc_action\n"); 757 printk("tca_action_flush: couldnt create tc_action\n");
@@ -763,7 +762,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
763 if (!skb) { 762 if (!skb) {
764 printk("tca_action_flush: failed skb alloc\n"); 763 printk("tca_action_flush: failed skb alloc\n");
765 kfree(a); 764 kfree(a);
766 return -ENOBUFS; 765 return err;
767 } 766 }
768 767
769 b = skb_tail_pointer(skb); 768 b = skb_tail_pointer(skb);
@@ -791,6 +790,8 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
791 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); 790 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
792 if (err < 0) 791 if (err < 0)
793 goto nla_put_failure; 792 goto nla_put_failure;
793 if (err == 0)
794 goto noflush_out;
794 795
795 nla_nest_end(skb, nest); 796 nla_nest_end(skb, nest);
796 797
@@ -808,6 +809,7 @@ nla_put_failure:
808nlmsg_failure: 809nlmsg_failure:
809 module_put(a->ops->owner); 810 module_put(a->ops->owner);
810err_out: 811err_out:
812noflush_out:
811 kfree_skb(skb); 813 kfree_skb(skb);
812 kfree(a); 814 kfree(a);
813 return err; 815 return err;
@@ -825,8 +827,10 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
825 return ret; 827 return ret;
826 828
827 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { 829 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
828 if (tb[0] != NULL && tb[1] == NULL) 830 if (tb[1] != NULL)
829 return tca_action_flush(tb[0], n, pid); 831 return tca_action_flush(tb[1], n, pid);
832 else
833 return -EINVAL;
830 } 834 }
831 835
832 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { 836 for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index d2b6f54a6261..5cafdd4c8018 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -280,7 +280,7 @@ replay:
280 if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { 280 if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
281 spin_lock_bh(root_lock); 281 spin_lock_bh(root_lock);
282 *back = tp->next; 282 *back = tp->next;
283 spin_lock_bh(root_lock); 283 spin_unlock_bh(root_lock);
284 284
285 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 285 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER);
286 tcf_destroy(tp); 286 tcf_destroy(tp);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 4840aff47256..e7fb9e0d21b4 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -27,6 +27,7 @@
27#include <linux/kmod.h> 27#include <linux/kmod.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/hrtimer.h> 29#include <linux/hrtimer.h>
30#include <linux/lockdep.h>
30 31
31#include <net/net_namespace.h> 32#include <net/net_namespace.h>
32#include <net/sock.h> 33#include <net/sock.h>
@@ -183,24 +184,68 @@ EXPORT_SYMBOL(unregister_qdisc);
183 (root qdisc, all its children, children of children etc.) 184 (root qdisc, all its children, children of children etc.)
184 */ 185 */
185 186
187struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
188{
189 struct Qdisc *q;
190
191 if (!(root->flags & TCQ_F_BUILTIN) &&
192 root->handle == handle)
193 return root;
194
195 list_for_each_entry(q, &root->list, list) {
196 if (q->handle == handle)
197 return q;
198 }
199 return NULL;
200}
201
202/*
203 * This lock is needed until some qdiscs stop calling qdisc_tree_decrease_qlen()
204 * without rtnl_lock(); currently hfsc_dequeue(), netem_dequeue(), tbf_dequeue()
205 */
206static DEFINE_SPINLOCK(qdisc_list_lock);
207
208static void qdisc_list_add(struct Qdisc *q)
209{
210 if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
211 spin_lock_bh(&qdisc_list_lock);
212 list_add_tail(&q->list, &qdisc_root_sleeping(q)->list);
213 spin_unlock_bh(&qdisc_list_lock);
214 }
215}
216
217void qdisc_list_del(struct Qdisc *q)
218{
219 if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
220 spin_lock_bh(&qdisc_list_lock);
221 list_del(&q->list);
222 spin_unlock_bh(&qdisc_list_lock);
223 }
224}
225EXPORT_SYMBOL(qdisc_list_del);
226
186struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) 227struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
187{ 228{
188 unsigned int i; 229 unsigned int i;
230 struct Qdisc *q;
231
232 spin_lock_bh(&qdisc_list_lock);
189 233
190 for (i = 0; i < dev->num_tx_queues; i++) { 234 for (i = 0; i < dev->num_tx_queues; i++) {
191 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 235 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
192 struct Qdisc *q, *txq_root = txq->qdisc; 236 struct Qdisc *txq_root = txq->qdisc_sleeping;
193
194 if (!(txq_root->flags & TCQ_F_BUILTIN) &&
195 txq_root->handle == handle)
196 return txq_root;
197 237
198 list_for_each_entry(q, &txq_root->list, list) { 238 q = qdisc_match_from_root(txq_root, handle);
199 if (q->handle == handle) 239 if (q)
200 return q; 240 goto unlock;
201 }
202 } 241 }
203 return NULL; 242
243 q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
244
245unlock:
246 spin_unlock_bh(&qdisc_list_lock);
247
248 return q;
204} 249}
205 250
206static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) 251static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
@@ -416,7 +461,7 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
416 461
417 wd->qdisc->flags &= ~TCQ_F_THROTTLED; 462 wd->qdisc->flags &= ~TCQ_F_THROTTLED;
418 smp_wmb(); 463 smp_wmb();
419 __netif_schedule(wd->qdisc); 464 __netif_schedule(qdisc_root(wd->qdisc));
420 465
421 return HRTIMER_NORESTART; 466 return HRTIMER_NORESTART;
422} 467}
@@ -433,6 +478,10 @@ void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
433{ 478{
434 ktime_t time; 479 ktime_t time;
435 480
481 if (test_bit(__QDISC_STATE_DEACTIVATED,
482 &qdisc_root_sleeping(wd->qdisc)->state))
483 return;
484
436 wd->qdisc->flags |= TCQ_F_THROTTLED; 485 wd->qdisc->flags |= TCQ_F_THROTTLED;
437 time = ktime_set(0, 0); 486 time = ktime_set(0, 0);
438 time = ktime_add_ns(time, PSCHED_US2NS(expires)); 487 time = ktime_add_ns(time, PSCHED_US2NS(expires));
@@ -627,11 +676,8 @@ static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid
627 if (new || old) 676 if (new || old)
628 qdisc_notify(skb, n, clid, old, new); 677 qdisc_notify(skb, n, clid, old, new);
629 678
630 if (old) { 679 if (old)
631 spin_lock_bh(&old->q.lock);
632 qdisc_destroy(old); 680 qdisc_destroy(old);
633 spin_unlock_bh(&old->q.lock);
634 }
635} 681}
636 682
637/* Graft qdisc "new" to class "classid" of qdisc "parent" or 683/* Graft qdisc "new" to class "classid" of qdisc "parent" or
@@ -697,6 +743,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
697 return err; 743 return err;
698} 744}
699 745
746/* lockdep annotation is needed for ingress; egress gets it only for name */
747static struct lock_class_key qdisc_tx_lock;
748static struct lock_class_key qdisc_rx_lock;
749
700/* 750/*
701 Allocate and initialize new qdisc. 751 Allocate and initialize new qdisc.
702 752
@@ -757,6 +807,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
757 if (handle == TC_H_INGRESS) { 807 if (handle == TC_H_INGRESS) {
758 sch->flags |= TCQ_F_INGRESS; 808 sch->flags |= TCQ_F_INGRESS;
759 handle = TC_H_MAKE(TC_H_INGRESS, 0); 809 handle = TC_H_MAKE(TC_H_INGRESS, 0);
810 lockdep_set_class(qdisc_lock(sch), &qdisc_rx_lock);
760 } else { 811 } else {
761 if (handle == 0) { 812 if (handle == 0) {
762 handle = qdisc_alloc_handle(dev); 813 handle = qdisc_alloc_handle(dev);
@@ -764,6 +815,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
764 if (handle == 0) 815 if (handle == 0)
765 goto err_out3; 816 goto err_out3;
766 } 817 }
818 lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
767 } 819 }
768 820
769 sch->handle = handle; 821 sch->handle = handle;
@@ -792,8 +844,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
792 goto err_out3; 844 goto err_out3;
793 } 845 }
794 } 846 }
795 if (parent && !(sch->flags & TCQ_F_INGRESS)) 847
796 list_add_tail(&sch->list, &dev_queue->qdisc->list); 848 qdisc_list_add(sch);
797 849
798 return sch; 850 return sch;
799 } 851 }
@@ -908,7 +960,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
908 return -ENOENT; 960 return -ENOENT;
909 q = qdisc_leaf(p, clid); 961 q = qdisc_leaf(p, clid);
910 } else { /* ingress */ 962 } else { /* ingress */
911 q = dev->rx_queue.qdisc; 963 q = dev->rx_queue.qdisc_sleeping;
912 } 964 }
913 } else { 965 } else {
914 struct netdev_queue *dev_queue; 966 struct netdev_queue *dev_queue;
@@ -978,7 +1030,7 @@ replay:
978 return -ENOENT; 1030 return -ENOENT;
979 q = qdisc_leaf(p, clid); 1031 q = qdisc_leaf(p, clid);
980 } else { /*ingress */ 1032 } else { /*ingress */
981 q = dev->rx_queue.qdisc; 1033 q = dev->rx_queue.qdisc_sleeping;
982 } 1034 }
983 } else { 1035 } else {
984 struct netdev_queue *dev_queue; 1036 struct netdev_queue *dev_queue;
@@ -1074,20 +1126,13 @@ create_n_graft:
1074 } 1126 }
1075 1127
1076graft: 1128graft:
1077 if (1) { 1129 err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
1078 spinlock_t *root_lock; 1130 if (err) {
1079 1131 if (q)
1080 err = qdisc_graft(dev, p, skb, n, clid, q, NULL); 1132 qdisc_destroy(q);
1081 if (err) { 1133 return err;
1082 if (q) {
1083 root_lock = qdisc_root_lock(q);
1084 spin_lock_bh(root_lock);
1085 qdisc_destroy(q);
1086 spin_unlock_bh(root_lock);
1087 }
1088 return err;
1089 }
1090 } 1134 }
1135
1091 return 0; 1136 return 0;
1092} 1137}
1093 1138
@@ -1236,11 +1281,11 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
1236 q_idx = 0; 1281 q_idx = 0;
1237 1282
1238 dev_queue = netdev_get_tx_queue(dev, 0); 1283 dev_queue = netdev_get_tx_queue(dev, 0);
1239 if (tc_dump_qdisc_root(dev_queue->qdisc, skb, cb, &q_idx, s_q_idx) < 0) 1284 if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0)
1240 goto done; 1285 goto done;
1241 1286
1242 dev_queue = &dev->rx_queue; 1287 dev_queue = &dev->rx_queue;
1243 if (tc_dump_qdisc_root(dev_queue->qdisc, skb, cb, &q_idx, s_q_idx) < 0) 1288 if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0)
1244 goto done; 1289 goto done;
1245 1290
1246cont: 1291cont:
@@ -1529,11 +1574,11 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1529 t = 0; 1574 t = 0;
1530 1575
1531 dev_queue = netdev_get_tx_queue(dev, 0); 1576 dev_queue = netdev_get_tx_queue(dev, 0);
1532 if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) 1577 if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
1533 goto done; 1578 goto done;
1534 1579
1535 dev_queue = &dev->rx_queue; 1580 dev_queue = &dev->rx_queue;
1536 if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) 1581 if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
1537 goto done; 1582 goto done;
1538 1583
1539done: 1584done:
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 6b517b9dac5b..43d37256c15e 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -415,7 +415,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
415 case TC_ACT_QUEUED: 415 case TC_ACT_QUEUED:
416 case TC_ACT_STOLEN: 416 case TC_ACT_STOLEN:
417 kfree_skb(skb); 417 kfree_skb(skb);
418 return NET_XMIT_SUCCESS; 418 return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
419 case TC_ACT_SHOT: 419 case TC_ACT_SHOT:
420 kfree_skb(skb); 420 kfree_skb(skb);
421 goto drop; 421 goto drop;
@@ -432,9 +432,11 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
432 ret = qdisc_enqueue(skb, flow->q); 432 ret = qdisc_enqueue(skb, flow->q);
433 if (ret != 0) { 433 if (ret != 0) {
434drop: __maybe_unused 434drop: __maybe_unused
435 sch->qstats.drops++; 435 if (net_xmit_drop_count(ret)) {
436 if (flow) 436 sch->qstats.drops++;
437 flow->qstats.drops++; 437 if (flow)
438 flow->qstats.drops++;
439 }
438 return ret; 440 return ret;
439 } 441 }
440 sch->bstats.bytes += qdisc_pkt_len(skb); 442 sch->bstats.bytes += qdisc_pkt_len(skb);
@@ -455,7 +457,7 @@ drop: __maybe_unused
455 return 0; 457 return 0;
456 } 458 }
457 tasklet_schedule(&p->task); 459 tasklet_schedule(&p->task);
458 return NET_XMIT_BYPASS; 460 return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
459} 461}
460 462
461/* 463/*
@@ -530,7 +532,7 @@ static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
530 if (!ret) { 532 if (!ret) {
531 sch->q.qlen++; 533 sch->q.qlen++;
532 sch->qstats.requeues++; 534 sch->qstats.requeues++;
533 } else { 535 } else if (net_xmit_drop_count(ret)) {
534 sch->qstats.drops++; 536 sch->qstats.drops++;
535 p->link.qstats.drops++; 537 p->link.qstats.drops++;
536 } 538 }
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 14954bf4a683..8fa90d68ec6d 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -230,7 +230,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
230 (cl = cbq_class_lookup(q, prio)) != NULL) 230 (cl = cbq_class_lookup(q, prio)) != NULL)
231 return cl; 231 return cl;
232 232
233 *qerr = NET_XMIT_BYPASS; 233 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
234 for (;;) { 234 for (;;) {
235 int result = 0; 235 int result = 0;
236 defmap = head->defaults; 236 defmap = head->defaults;
@@ -256,7 +256,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
256 switch (result) { 256 switch (result) {
257 case TC_ACT_QUEUED: 257 case TC_ACT_QUEUED:
258 case TC_ACT_STOLEN: 258 case TC_ACT_STOLEN:
259 *qerr = NET_XMIT_SUCCESS; 259 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
260 case TC_ACT_SHOT: 260 case TC_ACT_SHOT:
261 return NULL; 261 return NULL;
262 case TC_ACT_RECLASSIFY: 262 case TC_ACT_RECLASSIFY:
@@ -377,7 +377,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
377 q->rx_class = cl; 377 q->rx_class = cl;
378#endif 378#endif
379 if (cl == NULL) { 379 if (cl == NULL) {
380 if (ret == NET_XMIT_BYPASS) 380 if (ret & __NET_XMIT_BYPASS)
381 sch->qstats.drops++; 381 sch->qstats.drops++;
382 kfree_skb(skb); 382 kfree_skb(skb);
383 return ret; 383 return ret;
@@ -397,9 +397,11 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
397 return ret; 397 return ret;
398 } 398 }
399 399
400 sch->qstats.drops++; 400 if (net_xmit_drop_count(ret)) {
401 cbq_mark_toplevel(q, cl); 401 sch->qstats.drops++;
402 cl->qstats.drops++; 402 cbq_mark_toplevel(q, cl);
403 cl->qstats.drops++;
404 }
403 return ret; 405 return ret;
404} 406}
405 407
@@ -430,8 +432,10 @@ cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
430 cbq_activate_class(cl); 432 cbq_activate_class(cl);
431 return 0; 433 return 0;
432 } 434 }
433 sch->qstats.drops++; 435 if (net_xmit_drop_count(ret)) {
434 cl->qstats.drops++; 436 sch->qstats.drops++;
437 cl->qstats.drops++;
438 }
435 return ret; 439 return ret;
436} 440}
437 441
@@ -517,6 +521,10 @@ static void cbq_ovl_delay(struct cbq_class *cl)
517 struct cbq_sched_data *q = qdisc_priv(cl->qdisc); 521 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
518 psched_tdiff_t delay = cl->undertime - q->now; 522 psched_tdiff_t delay = cl->undertime - q->now;
519 523
524 if (test_bit(__QDISC_STATE_DEACTIVATED,
525 &qdisc_root_sleeping(cl->qdisc)->state))
526 return;
527
520 if (!cl->delayed) { 528 if (!cl->delayed) {
521 psched_time_t sched = q->now; 529 psched_time_t sched = q->now;
522 ktime_t expires; 530 ktime_t expires;
@@ -650,7 +658,7 @@ static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
650 } 658 }
651 659
652 sch->flags &= ~TCQ_F_THROTTLED; 660 sch->flags &= ~TCQ_F_THROTTLED;
653 __netif_schedule(sch); 661 __netif_schedule(qdisc_root(sch));
654 return HRTIMER_NORESTART; 662 return HRTIMER_NORESTART;
655} 663}
656 664
@@ -664,13 +672,15 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
664 q->rx_class = NULL; 672 q->rx_class = NULL;
665 673
666 if (cl && (cl = cbq_reclassify(skb, cl)) != NULL) { 674 if (cl && (cl = cbq_reclassify(skb, cl)) != NULL) {
675 int ret;
667 676
668 cbq_mark_toplevel(q, cl); 677 cbq_mark_toplevel(q, cl);
669 678
670 q->rx_class = cl; 679 q->rx_class = cl;
671 cl->q->__parent = sch; 680 cl->q->__parent = sch;
672 681
673 if (qdisc_enqueue(skb, cl->q) == 0) { 682 ret = qdisc_enqueue(skb, cl->q);
683 if (ret == NET_XMIT_SUCCESS) {
674 sch->q.qlen++; 684 sch->q.qlen++;
675 sch->bstats.packets++; 685 sch->bstats.packets++;
676 sch->bstats.bytes += qdisc_pkt_len(skb); 686 sch->bstats.bytes += qdisc_pkt_len(skb);
@@ -678,7 +688,8 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
678 cbq_activate_class(cl); 688 cbq_activate_class(cl);
679 return 0; 689 return 0;
680 } 690 }
681 sch->qstats.drops++; 691 if (net_xmit_drop_count(ret))
692 sch->qstats.drops++;
682 return 0; 693 return 0;
683 } 694 }
684 695
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index a935676987e2..edd1298f85f6 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -236,7 +236,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
236 case TC_ACT_QUEUED: 236 case TC_ACT_QUEUED:
237 case TC_ACT_STOLEN: 237 case TC_ACT_STOLEN:
238 kfree_skb(skb); 238 kfree_skb(skb);
239 return NET_XMIT_SUCCESS; 239 return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
240 240
241 case TC_ACT_SHOT: 241 case TC_ACT_SHOT:
242 goto drop; 242 goto drop;
@@ -254,7 +254,8 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
254 254
255 err = qdisc_enqueue(skb, p->q); 255 err = qdisc_enqueue(skb, p->q);
256 if (err != NET_XMIT_SUCCESS) { 256 if (err != NET_XMIT_SUCCESS) {
257 sch->qstats.drops++; 257 if (net_xmit_drop_count(err))
258 sch->qstats.drops++;
258 return err; 259 return err;
259 } 260 }
260 261
@@ -267,7 +268,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
267drop: 268drop:
268 kfree_skb(skb); 269 kfree_skb(skb);
269 sch->qstats.drops++; 270 sch->qstats.drops++;
270 return NET_XMIT_BYPASS; 271 return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
271} 272}
272 273
273static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) 274static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
@@ -321,7 +322,8 @@ static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
321 322
322 err = p->q->ops->requeue(skb, p->q); 323 err = p->q->ops->requeue(skb, p->q);
323 if (err != NET_XMIT_SUCCESS) { 324 if (err != NET_XMIT_SUCCESS) {
324 sch->qstats.drops++; 325 if (net_xmit_drop_count(err))
326 sch->qstats.drops++;
325 return err; 327 return err;
326 } 328 }
327 329
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 345838a2e369..5f0ade7806a7 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -29,7 +29,7 @@
29/* Main transmission queue. */ 29/* Main transmission queue. */
30 30
31/* Modifications to data participating in scheduling must be protected with 31/* Modifications to data participating in scheduling must be protected with
32 * qdisc_root_lock(qdisc) spinlock. 32 * qdisc_lock(qdisc) spinlock.
33 * 33 *
34 * The idea is the following: 34 * The idea is the following:
35 * - enqueue, dequeue are serialized via qdisc root lock 35 * - enqueue, dequeue are serialized via qdisc root lock
@@ -126,7 +126,7 @@ static inline int qdisc_restart(struct Qdisc *q)
126 if (unlikely((skb = dequeue_skb(q)) == NULL)) 126 if (unlikely((skb = dequeue_skb(q)) == NULL))
127 return 0; 127 return 0;
128 128
129 root_lock = qdisc_root_lock(q); 129 root_lock = qdisc_lock(q);
130 130
131 /* And release qdisc */ 131 /* And release qdisc */
132 spin_unlock(root_lock); 132 spin_unlock(root_lock);
@@ -135,7 +135,8 @@ static inline int qdisc_restart(struct Qdisc *q)
135 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); 135 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
136 136
137 HARD_TX_LOCK(dev, txq, smp_processor_id()); 137 HARD_TX_LOCK(dev, txq, smp_processor_id());
138 if (!netif_subqueue_stopped(dev, skb)) 138 if (!netif_tx_queue_stopped(txq) &&
139 !netif_tx_queue_frozen(txq))
139 ret = dev_hard_start_xmit(skb, dev, txq); 140 ret = dev_hard_start_xmit(skb, dev, txq);
140 HARD_TX_UNLOCK(dev, txq); 141 HARD_TX_UNLOCK(dev, txq);
141 142
@@ -162,7 +163,8 @@ static inline int qdisc_restart(struct Qdisc *q)
162 break; 163 break;
163 } 164 }
164 165
165 if (ret && netif_tx_queue_stopped(txq)) 166 if (ret && (netif_tx_queue_stopped(txq) ||
167 netif_tx_queue_frozen(txq)))
166 ret = 0; 168 ret = 0;
167 169
168 return ret; 170 return ret;
@@ -505,7 +507,7 @@ errout:
505} 507}
506EXPORT_SYMBOL(qdisc_create_dflt); 508EXPORT_SYMBOL(qdisc_create_dflt);
507 509
508/* Under qdisc_root_lock(qdisc) and BH! */ 510/* Under qdisc_lock(qdisc) and BH! */
509 511
510void qdisc_reset(struct Qdisc *qdisc) 512void qdisc_reset(struct Qdisc *qdisc)
511{ 513{
@@ -516,15 +518,17 @@ void qdisc_reset(struct Qdisc *qdisc)
516} 518}
517EXPORT_SYMBOL(qdisc_reset); 519EXPORT_SYMBOL(qdisc_reset);
518 520
519/* this is the rcu callback function to clean up a qdisc when there 521void qdisc_destroy(struct Qdisc *qdisc)
520 * are no further references to it */
521
522static void __qdisc_destroy(struct rcu_head *head)
523{ 522{
524 struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu);
525 const struct Qdisc_ops *ops = qdisc->ops; 523 const struct Qdisc_ops *ops = qdisc->ops;
526 524
525 if (qdisc->flags & TCQ_F_BUILTIN ||
526 !atomic_dec_and_test(&qdisc->refcnt))
527 return;
528
527#ifdef CONFIG_NET_SCHED 529#ifdef CONFIG_NET_SCHED
530 qdisc_list_del(qdisc);
531
528 qdisc_put_stab(qdisc->stab); 532 qdisc_put_stab(qdisc->stab);
529#endif 533#endif
530 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); 534 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
@@ -540,20 +544,6 @@ static void __qdisc_destroy(struct rcu_head *head)
540 544
541 kfree((char *) qdisc - qdisc->padded); 545 kfree((char *) qdisc - qdisc->padded);
542} 546}
543
544/* Under qdisc_root_lock(qdisc) and BH! */
545
546void qdisc_destroy(struct Qdisc *qdisc)
547{
548 if (qdisc->flags & TCQ_F_BUILTIN ||
549 !atomic_dec_and_test(&qdisc->refcnt))
550 return;
551
552 if (qdisc->parent)
553 list_del(&qdisc->list);
554
555 call_rcu(&qdisc->q_rcu, __qdisc_destroy);
556}
557EXPORT_SYMBOL(qdisc_destroy); 547EXPORT_SYMBOL(qdisc_destroy);
558 548
559static bool dev_all_qdisc_sleeping_noop(struct net_device *dev) 549static bool dev_all_qdisc_sleeping_noop(struct net_device *dev)
@@ -595,6 +585,9 @@ static void transition_one_qdisc(struct net_device *dev,
595 struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping; 585 struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping;
596 int *need_watchdog_p = _need_watchdog; 586 int *need_watchdog_p = _need_watchdog;
597 587
588 if (!(new_qdisc->flags & TCQ_F_BUILTIN))
589 clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
590
598 rcu_assign_pointer(dev_queue->qdisc, new_qdisc); 591 rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
599 if (need_watchdog_p && new_qdisc != &noqueue_qdisc) 592 if (need_watchdog_p && new_qdisc != &noqueue_qdisc)
600 *need_watchdog_p = 1; 593 *need_watchdog_p = 1;
@@ -638,6 +631,9 @@ static void dev_deactivate_queue(struct net_device *dev,
638 if (qdisc) { 631 if (qdisc) {
639 spin_lock_bh(qdisc_lock(qdisc)); 632 spin_lock_bh(qdisc_lock(qdisc));
640 633
634 if (!(qdisc->flags & TCQ_F_BUILTIN))
635 set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state);
636
641 dev_queue->qdisc = qdisc_default; 637 dev_queue->qdisc = qdisc_default;
642 qdisc_reset(qdisc); 638 qdisc_reset(qdisc);
643 639
@@ -645,7 +641,7 @@ static void dev_deactivate_queue(struct net_device *dev,
645 } 641 }
646} 642}
647 643
648static bool some_qdisc_is_running(struct net_device *dev, int lock) 644static bool some_qdisc_is_busy(struct net_device *dev)
649{ 645{
650 unsigned int i; 646 unsigned int i;
651 647
@@ -656,16 +652,15 @@ static bool some_qdisc_is_running(struct net_device *dev, int lock)
656 int val; 652 int val;
657 653
658 dev_queue = netdev_get_tx_queue(dev, i); 654 dev_queue = netdev_get_tx_queue(dev, i);
659 q = dev_queue->qdisc; 655 q = dev_queue->qdisc_sleeping;
660 root_lock = qdisc_root_lock(q); 656 root_lock = qdisc_lock(q);
661 657
662 if (lock) 658 spin_lock_bh(root_lock);
663 spin_lock_bh(root_lock);
664 659
665 val = test_bit(__QDISC_STATE_RUNNING, &q->state); 660 val = (test_bit(__QDISC_STATE_RUNNING, &q->state) ||
661 test_bit(__QDISC_STATE_SCHED, &q->state));
666 662
667 if (lock) 663 spin_unlock_bh(root_lock);
668 spin_unlock_bh(root_lock);
669 664
670 if (val) 665 if (val)
671 return true; 666 return true;
@@ -675,8 +670,6 @@ static bool some_qdisc_is_running(struct net_device *dev, int lock)
675 670
676void dev_deactivate(struct net_device *dev) 671void dev_deactivate(struct net_device *dev)
677{ 672{
678 bool running;
679
680 netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); 673 netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc);
681 dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc); 674 dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc);
682 675
@@ -686,25 +679,8 @@ void dev_deactivate(struct net_device *dev)
686 synchronize_rcu(); 679 synchronize_rcu();
687 680
688 /* Wait for outstanding qdisc_run calls. */ 681 /* Wait for outstanding qdisc_run calls. */
689 do { 682 while (some_qdisc_is_busy(dev))
690 while (some_qdisc_is_running(dev, 0)) 683 yield();
691 yield();
692
693 /*
694 * Double-check inside queue lock to ensure that all effects
695 * of the queue run are visible when we return.
696 */
697 running = some_qdisc_is_running(dev, 1);
698
699 /*
700 * The running flag should never be set at this point because
701 * we've already set dev->qdisc to noop_qdisc *inside* the same
702 * pair of spin locks. That is, if any qdisc_run starts after
703 * our initial test it should see the noop_qdisc and then
704 * clear the RUNNING bit before dropping the queue lock. So
705 * if it is set here then we've found a bug.
706 */
707 } while (WARN_ON_ONCE(running));
708} 684}
709 685
710static void dev_init_scheduler_queue(struct net_device *dev, 686static void dev_init_scheduler_queue(struct net_device *dev,
@@ -733,14 +709,10 @@ static void shutdown_scheduler_queue(struct net_device *dev,
733 struct Qdisc *qdisc_default = _qdisc_default; 709 struct Qdisc *qdisc_default = _qdisc_default;
734 710
735 if (qdisc) { 711 if (qdisc) {
736 spinlock_t *root_lock = qdisc_root_lock(qdisc);
737
738 dev_queue->qdisc = qdisc_default; 712 dev_queue->qdisc = qdisc_default;
739 dev_queue->qdisc_sleeping = qdisc_default; 713 dev_queue->qdisc_sleeping = qdisc_default;
740 714
741 spin_lock_bh(root_lock);
742 qdisc_destroy(qdisc); 715 qdisc_destroy(qdisc);
743 spin_unlock_bh(root_lock);
744 } 716 }
745} 717}
746 718
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 0ae7d19dcba8..c2b8d9cce3d2 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1159,14 +1159,14 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
1159 if (cl->level == 0) 1159 if (cl->level == 0)
1160 return cl; 1160 return cl;
1161 1161
1162 *qerr = NET_XMIT_BYPASS; 1162 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
1163 tcf = q->root.filter_list; 1163 tcf = q->root.filter_list;
1164 while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) { 1164 while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
1165#ifdef CONFIG_NET_CLS_ACT 1165#ifdef CONFIG_NET_CLS_ACT
1166 switch (result) { 1166 switch (result) {
1167 case TC_ACT_QUEUED: 1167 case TC_ACT_QUEUED:
1168 case TC_ACT_STOLEN: 1168 case TC_ACT_STOLEN:
1169 *qerr = NET_XMIT_SUCCESS; 1169 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
1170 case TC_ACT_SHOT: 1170 case TC_ACT_SHOT:
1171 return NULL; 1171 return NULL;
1172 } 1172 }
@@ -1578,7 +1578,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
1578 1578
1579 cl = hfsc_classify(skb, sch, &err); 1579 cl = hfsc_classify(skb, sch, &err);
1580 if (cl == NULL) { 1580 if (cl == NULL) {
1581 if (err == NET_XMIT_BYPASS) 1581 if (err & __NET_XMIT_BYPASS)
1582 sch->qstats.drops++; 1582 sch->qstats.drops++;
1583 kfree_skb(skb); 1583 kfree_skb(skb);
1584 return err; 1584 return err;
@@ -1586,8 +1586,10 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
1586 1586
1587 err = qdisc_enqueue(skb, cl->qdisc); 1587 err = qdisc_enqueue(skb, cl->qdisc);
1588 if (unlikely(err != NET_XMIT_SUCCESS)) { 1588 if (unlikely(err != NET_XMIT_SUCCESS)) {
1589 cl->qstats.drops++; 1589 if (net_xmit_drop_count(err)) {
1590 sch->qstats.drops++; 1590 cl->qstats.drops++;
1591 sch->qstats.drops++;
1592 }
1591 return err; 1593 return err;
1592 } 1594 }
1593 1595
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 75a40951c4f2..0df0df202ed0 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -214,14 +214,14 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch,
214 if ((cl = htb_find(skb->priority, sch)) != NULL && cl->level == 0) 214 if ((cl = htb_find(skb->priority, sch)) != NULL && cl->level == 0)
215 return cl; 215 return cl;
216 216
217 *qerr = NET_XMIT_BYPASS; 217 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
218 tcf = q->filter_list; 218 tcf = q->filter_list;
219 while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) { 219 while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
220#ifdef CONFIG_NET_CLS_ACT 220#ifdef CONFIG_NET_CLS_ACT
221 switch (result) { 221 switch (result) {
222 case TC_ACT_QUEUED: 222 case TC_ACT_QUEUED:
223 case TC_ACT_STOLEN: 223 case TC_ACT_STOLEN:
224 *qerr = NET_XMIT_SUCCESS; 224 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
225 case TC_ACT_SHOT: 225 case TC_ACT_SHOT:
226 return NULL; 226 return NULL;
227 } 227 }
@@ -567,15 +567,17 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
567 } 567 }
568#ifdef CONFIG_NET_CLS_ACT 568#ifdef CONFIG_NET_CLS_ACT
569 } else if (!cl) { 569 } else if (!cl) {
570 if (ret == NET_XMIT_BYPASS) 570 if (ret & __NET_XMIT_BYPASS)
571 sch->qstats.drops++; 571 sch->qstats.drops++;
572 kfree_skb(skb); 572 kfree_skb(skb);
573 return ret; 573 return ret;
574#endif 574#endif
575 } else if (qdisc_enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { 575 } else if ((ret = qdisc_enqueue(skb, cl->un.leaf.q)) != NET_XMIT_SUCCESS) {
576 sch->qstats.drops++; 576 if (net_xmit_drop_count(ret)) {
577 cl->qstats.drops++; 577 sch->qstats.drops++;
578 return NET_XMIT_DROP; 578 cl->qstats.drops++;
579 }
580 return ret;
579 } else { 581 } else {
580 cl->bstats.packets += 582 cl->bstats.packets +=
581 skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1; 583 skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
@@ -610,16 +612,18 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
610 } 612 }
611#ifdef CONFIG_NET_CLS_ACT 613#ifdef CONFIG_NET_CLS_ACT
612 } else if (!cl) { 614 } else if (!cl) {
613 if (ret == NET_XMIT_BYPASS) 615 if (ret & __NET_XMIT_BYPASS)
614 sch->qstats.drops++; 616 sch->qstats.drops++;
615 kfree_skb(skb); 617 kfree_skb(skb);
616 return ret; 618 return ret;
617#endif 619#endif
618 } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != 620 } else if ((ret = cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q)) !=
619 NET_XMIT_SUCCESS) { 621 NET_XMIT_SUCCESS) {
620 sch->qstats.drops++; 622 if (net_xmit_drop_count(ret)) {
621 cl->qstats.drops++; 623 sch->qstats.drops++;
622 return NET_XMIT_DROP; 624 cl->qstats.drops++;
625 }
626 return ret;
623 } else 627 } else
624 htb_activate(q, cl); 628 htb_activate(q, cl);
625 629
@@ -1275,7 +1279,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
1275 1279
1276 /* delete from hash and active; remainder in destroy_class */ 1280 /* delete from hash and active; remainder in destroy_class */
1277 qdisc_class_hash_remove(&q->clhash, &cl->common); 1281 qdisc_class_hash_remove(&q->clhash, &cl->common);
1278 cl->parent->children--; 1282 if (cl->parent)
1283 cl->parent->children--;
1279 1284
1280 if (cl->prio_activity) 1285 if (cl->prio_activity)
1281 htb_deactivate(q, cl); 1286 htb_deactivate(q, cl);
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index a59085700678..fb0294d0b55e 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -176,7 +176,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
176 if (count == 0) { 176 if (count == 0) {
177 sch->qstats.drops++; 177 sch->qstats.drops++;
178 kfree_skb(skb); 178 kfree_skb(skb);
179 return NET_XMIT_BYPASS; 179 return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
180 } 180 }
181 181
182 skb_orphan(skb); 182 skb_orphan(skb);
@@ -240,8 +240,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
240 sch->q.qlen++; 240 sch->q.qlen++;
241 sch->bstats.bytes += qdisc_pkt_len(skb); 241 sch->bstats.bytes += qdisc_pkt_len(skb);
242 sch->bstats.packets++; 242 sch->bstats.packets++;
243 } else 243 } else if (net_xmit_drop_count(ret)) {
244 sch->qstats.drops++; 244 sch->qstats.drops++;
245 }
245 246
246 pr_debug("netem: enqueue ret %d\n", ret); 247 pr_debug("netem: enqueue ret %d\n", ret);
247 return ret; 248 return ret;
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index f849243eb095..a6697c686c7f 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -38,14 +38,14 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
38 struct tcf_result res; 38 struct tcf_result res;
39 int err; 39 int err;
40 40
41 *qerr = NET_XMIT_BYPASS; 41 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
42 if (TC_H_MAJ(skb->priority) != sch->handle) { 42 if (TC_H_MAJ(skb->priority) != sch->handle) {
43 err = tc_classify(skb, q->filter_list, &res); 43 err = tc_classify(skb, q->filter_list, &res);
44#ifdef CONFIG_NET_CLS_ACT 44#ifdef CONFIG_NET_CLS_ACT
45 switch (err) { 45 switch (err) {
46 case TC_ACT_STOLEN: 46 case TC_ACT_STOLEN:
47 case TC_ACT_QUEUED: 47 case TC_ACT_QUEUED:
48 *qerr = NET_XMIT_SUCCESS; 48 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
49 case TC_ACT_SHOT: 49 case TC_ACT_SHOT:
50 return NULL; 50 return NULL;
51 } 51 }
@@ -74,7 +74,7 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
74#ifdef CONFIG_NET_CLS_ACT 74#ifdef CONFIG_NET_CLS_ACT
75 if (qdisc == NULL) { 75 if (qdisc == NULL) {
76 76
77 if (ret == NET_XMIT_BYPASS) 77 if (ret & __NET_XMIT_BYPASS)
78 sch->qstats.drops++; 78 sch->qstats.drops++;
79 kfree_skb(skb); 79 kfree_skb(skb);
80 return ret; 80 return ret;
@@ -88,7 +88,8 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
88 sch->q.qlen++; 88 sch->q.qlen++;
89 return NET_XMIT_SUCCESS; 89 return NET_XMIT_SUCCESS;
90 } 90 }
91 sch->qstats.drops++; 91 if (net_xmit_drop_count(ret))
92 sch->qstats.drops++;
92 return ret; 93 return ret;
93} 94}
94 95
@@ -102,7 +103,7 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
102 qdisc = prio_classify(skb, sch, &ret); 103 qdisc = prio_classify(skb, sch, &ret);
103#ifdef CONFIG_NET_CLS_ACT 104#ifdef CONFIG_NET_CLS_ACT
104 if (qdisc == NULL) { 105 if (qdisc == NULL) {
105 if (ret == NET_XMIT_BYPASS) 106 if (ret & __NET_XMIT_BYPASS)
106 sch->qstats.drops++; 107 sch->qstats.drops++;
107 kfree_skb(skb); 108 kfree_skb(skb);
108 return ret; 109 return ret;
@@ -112,10 +113,11 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
112 if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) { 113 if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) {
113 sch->q.qlen++; 114 sch->q.qlen++;
114 sch->qstats.requeues++; 115 sch->qstats.requeues++;
115 return 0; 116 return NET_XMIT_SUCCESS;
116 } 117 }
117 sch->qstats.drops++; 118 if (net_xmit_drop_count(ret))
118 return NET_XMIT_DROP; 119 sch->qstats.drops++;
120 return ret;
119} 121}
120 122
121 123
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 3f2d1d7f3bbd..5da05839e225 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -97,7 +97,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
97 sch->bstats.bytes += qdisc_pkt_len(skb); 97 sch->bstats.bytes += qdisc_pkt_len(skb);
98 sch->bstats.packets++; 98 sch->bstats.packets++;
99 sch->q.qlen++; 99 sch->q.qlen++;
100 } else { 100 } else if (net_xmit_drop_count(ret)) {
101 q->stats.pdrop++; 101 q->stats.pdrop++;
102 sch->qstats.drops++; 102 sch->qstats.drops++;
103 } 103 }
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 8589da666568..6e041d10dbdb 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -171,14 +171,14 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
171 if (!q->filter_list) 171 if (!q->filter_list)
172 return sfq_hash(q, skb) + 1; 172 return sfq_hash(q, skb) + 1;
173 173
174 *qerr = NET_XMIT_BYPASS; 174 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
175 result = tc_classify(skb, q->filter_list, &res); 175 result = tc_classify(skb, q->filter_list, &res);
176 if (result >= 0) { 176 if (result >= 0) {
177#ifdef CONFIG_NET_CLS_ACT 177#ifdef CONFIG_NET_CLS_ACT
178 switch (result) { 178 switch (result) {
179 case TC_ACT_STOLEN: 179 case TC_ACT_STOLEN:
180 case TC_ACT_QUEUED: 180 case TC_ACT_QUEUED:
181 *qerr = NET_XMIT_SUCCESS; 181 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
182 case TC_ACT_SHOT: 182 case TC_ACT_SHOT:
183 return 0; 183 return 0;
184 } 184 }
@@ -285,7 +285,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
285 285
286 hash = sfq_classify(skb, sch, &ret); 286 hash = sfq_classify(skb, sch, &ret);
287 if (hash == 0) { 287 if (hash == 0) {
288 if (ret == NET_XMIT_BYPASS) 288 if (ret & __NET_XMIT_BYPASS)
289 sch->qstats.drops++; 289 sch->qstats.drops++;
290 kfree_skb(skb); 290 kfree_skb(skb);
291 return ret; 291 return ret;
@@ -339,7 +339,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc *sch)
339 339
340 hash = sfq_classify(skb, sch, &ret); 340 hash = sfq_classify(skb, sch, &ret);
341 if (hash == 0) { 341 if (hash == 0) {
342 if (ret == NET_XMIT_BYPASS) 342 if (ret & __NET_XMIT_BYPASS)
343 sch->qstats.drops++; 343 sch->qstats.drops++;
344 kfree_skb(skb); 344 kfree_skb(skb);
345 return ret; 345 return ret;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index b296672f7632..94c61598b86a 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -123,19 +123,13 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
123 struct tbf_sched_data *q = qdisc_priv(sch); 123 struct tbf_sched_data *q = qdisc_priv(sch);
124 int ret; 124 int ret;
125 125
126 if (qdisc_pkt_len(skb) > q->max_size) { 126 if (qdisc_pkt_len(skb) > q->max_size)
127 sch->qstats.drops++; 127 return qdisc_reshape_fail(skb, sch);
128#ifdef CONFIG_NET_CLS_ACT
129 if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
130#endif
131 kfree_skb(skb);
132
133 return NET_XMIT_DROP;
134 }
135 128
136 ret = qdisc_enqueue(skb, q->qdisc); 129 ret = qdisc_enqueue(skb, q->qdisc);
137 if (ret != 0) { 130 if (ret != 0) {
138 sch->qstats.drops++; 131 if (net_xmit_drop_count(ret))
132 sch->qstats.drops++;
139 return ret; 133 return ret;
140 } 134 }
141 135
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 537223642b6e..2c35c678563b 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -305,10 +305,11 @@ restart:
305 305
306 switch (teql_resolve(skb, skb_res, slave)) { 306 switch (teql_resolve(skb, skb_res, slave)) {
307 case 0: 307 case 0:
308 if (netif_tx_trylock(slave)) { 308 if (__netif_tx_trylock(slave_txq)) {
309 if (!__netif_subqueue_stopped(slave, subq) && 309 if (!netif_tx_queue_stopped(slave_txq) &&
310 !netif_tx_queue_frozen(slave_txq) &&
310 slave->hard_start_xmit(skb, slave) == 0) { 311 slave->hard_start_xmit(skb, slave) == 0) {
311 netif_tx_unlock(slave); 312 __netif_tx_unlock(slave_txq);
312 master->slaves = NEXT_SLAVE(q); 313 master->slaves = NEXT_SLAVE(q);
313 netif_wake_queue(dev); 314 netif_wake_queue(dev);
314 master->stats.tx_packets++; 315 master->stats.tx_packets++;
@@ -316,7 +317,7 @@ restart:
316 qdisc_pkt_len(skb); 317 qdisc_pkt_len(skb);
317 return 0; 318 return 0;
318 } 319 }
319 netif_tx_unlock(slave); 320 __netif_tx_unlock(slave_txq);
320 } 321 }
321 if (netif_queue_stopped(dev)) 322 if (netif_queue_stopped(dev))
322 busy = 1; 323 busy = 1;