aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-09-01 06:32:13 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-09-01 06:32:13 -0400
commit9d7548d4ca3c52ecb58f098a32b0756cdf8f96ee (patch)
tree651f7058bbaa2d8b2855286380d614afcf505118 /net/sched
parent31db6e9ea1dbdcf66b8227b4f7035dee1b1dd8c0 (diff)
parentbef69ea0dcce574a425feb0a5aa4c63dd108b9a6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/act_api.c13
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sched/sch_api.c131
-rw-r--r--net/sched/sch_cbq.c10
-rw-r--r--net/sched/sch_generic.c76
-rw-r--r--net/sched/sch_hfsc.c4
-rw-r--r--net/sched/sch_htb.c11
-rw-r--r--net/sched/sch_prio.c4
-rw-r--r--net/sched/sch_tbf.c11
9 files changed, 144 insertions, 118 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 26c7e1f9a350..9974b3f04f05 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -751,7 +751,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
751 struct nlattr *tb[TCA_ACT_MAX+1]; 751 struct nlattr *tb[TCA_ACT_MAX+1];
752 struct nlattr *kind; 752 struct nlattr *kind;
753 struct tc_action *a = create_a(0); 753 struct tc_action *a = create_a(0);
754 int err = -EINVAL; 754 int err = -ENOMEM;
755 755
756 if (a == NULL) { 756 if (a == NULL) {
757 printk("tca_action_flush: couldnt create tc_action\n"); 757 printk("tca_action_flush: couldnt create tc_action\n");
@@ -762,7 +762,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
762 if (!skb) { 762 if (!skb) {
763 printk("tca_action_flush: failed skb alloc\n"); 763 printk("tca_action_flush: failed skb alloc\n");
764 kfree(a); 764 kfree(a);
765 return -ENOBUFS; 765 return err;
766 } 766 }
767 767
768 b = skb_tail_pointer(skb); 768 b = skb_tail_pointer(skb);
@@ -790,6 +790,8 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
790 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); 790 err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
791 if (err < 0) 791 if (err < 0)
792 goto nla_put_failure; 792 goto nla_put_failure;
793 if (err == 0)
794 goto noflush_out;
793 795
794 nla_nest_end(skb, nest); 796 nla_nest_end(skb, nest);
795 797
@@ -807,6 +809,7 @@ nla_put_failure:
807nlmsg_failure: 809nlmsg_failure:
808 module_put(a->ops->owner); 810 module_put(a->ops->owner);
809err_out: 811err_out:
812noflush_out:
810 kfree_skb(skb); 813 kfree_skb(skb);
811 kfree(a); 814 kfree(a);
812 return err; 815 return err;
@@ -824,8 +827,10 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
824 return ret; 827 return ret;
825 828
826 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { 829 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
827 if (tb[0] != NULL && tb[1] == NULL) 830 if (tb[1] != NULL)
828 return tca_action_flush(tb[0], n, pid); 831 return tca_action_flush(tb[1], n, pid);
832 else
833 return -EINVAL;
829 } 834 }
830 835
831 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 ba1d121f3127..506b709510b6 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_sleeping; 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));
@@ -575,7 +624,7 @@ static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
575 struct Qdisc *oqdisc = dev_queue->qdisc_sleeping; 624 struct Qdisc *oqdisc = dev_queue->qdisc_sleeping;
576 spinlock_t *root_lock; 625 spinlock_t *root_lock;
577 626
578 root_lock = qdisc_root_lock(oqdisc); 627 root_lock = qdisc_lock(oqdisc);
579 spin_lock_bh(root_lock); 628 spin_lock_bh(root_lock);
580 629
581 /* Prune old scheduler */ 630 /* Prune old scheduler */
@@ -586,7 +635,7 @@ static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
586 if (qdisc == NULL) 635 if (qdisc == NULL)
587 qdisc = &noop_qdisc; 636 qdisc = &noop_qdisc;
588 dev_queue->qdisc_sleeping = qdisc; 637 dev_queue->qdisc_sleeping = qdisc;
589 dev_queue->qdisc = &noop_qdisc; 638 rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc);
590 639
591 spin_unlock_bh(root_lock); 640 spin_unlock_bh(root_lock);
592 641
@@ -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;
@@ -778,9 +830,16 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
778 sch->stab = stab; 830 sch->stab = stab;
779 } 831 }
780 if (tca[TCA_RATE]) { 832 if (tca[TCA_RATE]) {
833 spinlock_t *root_lock;
834
835 if ((sch->parent != TC_H_ROOT) &&
836 !(sch->flags & TCQ_F_INGRESS))
837 root_lock = qdisc_root_sleeping_lock(sch);
838 else
839 root_lock = qdisc_lock(sch);
840
781 err = gen_new_estimator(&sch->bstats, &sch->rate_est, 841 err = gen_new_estimator(&sch->bstats, &sch->rate_est,
782 qdisc_root_lock(sch), 842 root_lock, tca[TCA_RATE]);
783 tca[TCA_RATE]);
784 if (err) { 843 if (err) {
785 /* 844 /*
786 * Any broken qdiscs that would require 845 * Any broken qdiscs that would require
@@ -792,8 +851,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
792 goto err_out3; 851 goto err_out3;
793 } 852 }
794 } 853 }
795 if ((parent != TC_H_ROOT) && !(sch->flags & TCQ_F_INGRESS)) 854
796 list_add_tail(&sch->list, &dev_queue->qdisc_sleeping->list); 855 qdisc_list_add(sch);
797 856
798 return sch; 857 return sch;
799 } 858 }
@@ -832,7 +891,8 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
832 891
833 if (tca[TCA_RATE]) 892 if (tca[TCA_RATE])
834 gen_replace_estimator(&sch->bstats, &sch->rate_est, 893 gen_replace_estimator(&sch->bstats, &sch->rate_est,
835 qdisc_root_lock(sch), tca[TCA_RATE]); 894 qdisc_root_sleeping_lock(sch),
895 tca[TCA_RATE]);
836 return 0; 896 return 0;
837} 897}
838 898
@@ -908,7 +968,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
908 return -ENOENT; 968 return -ENOENT;
909 q = qdisc_leaf(p, clid); 969 q = qdisc_leaf(p, clid);
910 } else { /* ingress */ 970 } else { /* ingress */
911 q = dev->rx_queue.qdisc; 971 q = dev->rx_queue.qdisc_sleeping;
912 } 972 }
913 } else { 973 } else {
914 struct netdev_queue *dev_queue; 974 struct netdev_queue *dev_queue;
@@ -978,7 +1038,7 @@ replay:
978 return -ENOENT; 1038 return -ENOENT;
979 q = qdisc_leaf(p, clid); 1039 q = qdisc_leaf(p, clid);
980 } else { /*ingress */ 1040 } else { /*ingress */
981 q = dev->rx_queue.qdisc; 1041 q = dev->rx_queue.qdisc_sleeping;
982 } 1042 }
983 } else { 1043 } else {
984 struct netdev_queue *dev_queue; 1044 struct netdev_queue *dev_queue;
@@ -1074,20 +1134,13 @@ create_n_graft:
1074 } 1134 }
1075 1135
1076graft: 1136graft:
1077 if (1) { 1137 err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
1078 spinlock_t *root_lock; 1138 if (err) {
1079 1139 if (q)
1080 err = qdisc_graft(dev, p, skb, n, clid, q, NULL); 1140 qdisc_destroy(q);
1081 if (err) { 1141 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 } 1142 }
1143
1091 return 0; 1144 return 0;
1092} 1145}
1093 1146
@@ -1529,11 +1582,11 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1529 t = 0; 1582 t = 0;
1530 1583
1531 dev_queue = netdev_get_tx_queue(dev, 0); 1584 dev_queue = netdev_get_tx_queue(dev, 0);
1532 if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) 1585 if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
1533 goto done; 1586 goto done;
1534 1587
1535 dev_queue = &dev->rx_queue; 1588 dev_queue = &dev->rx_queue;
1536 if (tc_dump_tclass_root(dev_queue->qdisc, skb, tcm, cb, &t, s_t) < 0) 1589 if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
1537 goto done; 1590 goto done;
1538 1591
1539done: 1592done:
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 4e261ce62f48..9b720adedead 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -521,6 +521,10 @@ static void cbq_ovl_delay(struct cbq_class *cl)
521 struct cbq_sched_data *q = qdisc_priv(cl->qdisc); 521 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
522 psched_tdiff_t delay = cl->undertime - q->now; 522 psched_tdiff_t delay = cl->undertime - q->now;
523 523
524 if (test_bit(__QDISC_STATE_DEACTIVATED,
525 &qdisc_root_sleeping(cl->qdisc)->state))
526 return;
527
524 if (!cl->delayed) { 528 if (!cl->delayed) {
525 psched_time_t sched = q->now; 529 psched_time_t sched = q->now;
526 ktime_t expires; 530 ktime_t expires;
@@ -654,7 +658,7 @@ static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
654 } 658 }
655 659
656 sch->flags &= ~TCQ_F_THROTTLED; 660 sch->flags &= ~TCQ_F_THROTTLED;
657 __netif_schedule(sch); 661 __netif_schedule(qdisc_root(sch));
658 return HRTIMER_NORESTART; 662 return HRTIMER_NORESTART;
659} 663}
660 664
@@ -1835,7 +1839,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1835 1839
1836 if (tca[TCA_RATE]) 1840 if (tca[TCA_RATE])
1837 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1841 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1838 qdisc_root_lock(sch), 1842 qdisc_root_sleeping_lock(sch),
1839 tca[TCA_RATE]); 1843 tca[TCA_RATE]);
1840 return 0; 1844 return 0;
1841 } 1845 }
@@ -1926,7 +1930,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
1926 1930
1927 if (tca[TCA_RATE]) 1931 if (tca[TCA_RATE])
1928 gen_new_estimator(&cl->bstats, &cl->rate_est, 1932 gen_new_estimator(&cl->bstats, &cl->rate_est,
1929 qdisc_root_lock(sch), tca[TCA_RATE]); 1933 qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
1930 1934
1931 *arg = (unsigned long)cl; 1935 *arg = (unsigned long)cl;
1932 return 0; 1936 return 0;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7cf83b37459d..9634091ee2f0 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -518,15 +518,17 @@ void qdisc_reset(struct Qdisc *qdisc)
518} 518}
519EXPORT_SYMBOL(qdisc_reset); 519EXPORT_SYMBOL(qdisc_reset);
520 520
521/* this is the rcu callback function to clean up a qdisc when there 521void qdisc_destroy(struct Qdisc *qdisc)
522 * are no further references to it */
523
524static void __qdisc_destroy(struct rcu_head *head)
525{ 522{
526 struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu);
527 const struct Qdisc_ops *ops = qdisc->ops; 523 const struct Qdisc_ops *ops = qdisc->ops;
528 524
525 if (qdisc->flags & TCQ_F_BUILTIN ||
526 !atomic_dec_and_test(&qdisc->refcnt))
527 return;
528
529#ifdef CONFIG_NET_SCHED 529#ifdef CONFIG_NET_SCHED
530 qdisc_list_del(qdisc);
531
530 qdisc_put_stab(qdisc->stab); 532 qdisc_put_stab(qdisc->stab);
531#endif 533#endif
532 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); 534 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
@@ -542,20 +544,6 @@ static void __qdisc_destroy(struct rcu_head *head)
542 544
543 kfree((char *) qdisc - qdisc->padded); 545 kfree((char *) qdisc - qdisc->padded);
544} 546}
545
546/* Under qdisc_lock(qdisc) and BH! */
547
548void qdisc_destroy(struct Qdisc *qdisc)
549{
550 if (qdisc->flags & TCQ_F_BUILTIN ||
551 !atomic_dec_and_test(&qdisc->refcnt))
552 return;
553
554 if (qdisc->parent)
555 list_del(&qdisc->list);
556
557 call_rcu(&qdisc->q_rcu, __qdisc_destroy);
558}
559EXPORT_SYMBOL(qdisc_destroy); 547EXPORT_SYMBOL(qdisc_destroy);
560 548
561static bool dev_all_qdisc_sleeping_noop(struct net_device *dev) 549static bool dev_all_qdisc_sleeping_noop(struct net_device *dev)
@@ -597,6 +585,9 @@ static void transition_one_qdisc(struct net_device *dev,
597 struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping; 585 struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping;
598 int *need_watchdog_p = _need_watchdog; 586 int *need_watchdog_p = _need_watchdog;
599 587
588 if (!(new_qdisc->flags & TCQ_F_BUILTIN))
589 clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
590
600 rcu_assign_pointer(dev_queue->qdisc, new_qdisc); 591 rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
601 if (need_watchdog_p && new_qdisc != &noqueue_qdisc) 592 if (need_watchdog_p && new_qdisc != &noqueue_qdisc)
602 *need_watchdog_p = 1; 593 *need_watchdog_p = 1;
@@ -640,14 +631,17 @@ static void dev_deactivate_queue(struct net_device *dev,
640 if (qdisc) { 631 if (qdisc) {
641 spin_lock_bh(qdisc_lock(qdisc)); 632 spin_lock_bh(qdisc_lock(qdisc));
642 633
643 dev_queue->qdisc = qdisc_default; 634 if (!(qdisc->flags & TCQ_F_BUILTIN))
635 set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state);
636
637 rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
644 qdisc_reset(qdisc); 638 qdisc_reset(qdisc);
645 639
646 spin_unlock_bh(qdisc_lock(qdisc)); 640 spin_unlock_bh(qdisc_lock(qdisc));
647 } 641 }
648} 642}
649 643
650static bool some_qdisc_is_running(struct net_device *dev, int lock) 644static bool some_qdisc_is_busy(struct net_device *dev)
651{ 645{
652 unsigned int i; 646 unsigned int i;
653 647
@@ -658,16 +652,15 @@ static bool some_qdisc_is_running(struct net_device *dev, int lock)
658 int val; 652 int val;
659 653
660 dev_queue = netdev_get_tx_queue(dev, i); 654 dev_queue = netdev_get_tx_queue(dev, i);
661 q = dev_queue->qdisc; 655 q = dev_queue->qdisc_sleeping;
662 root_lock = qdisc_lock(q); 656 root_lock = qdisc_lock(q);
663 657
664 if (lock) 658 spin_lock_bh(root_lock);
665 spin_lock_bh(root_lock);
666 659
667 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));
668 662
669 if (lock) 663 spin_unlock_bh(root_lock);
670 spin_unlock_bh(root_lock);
671 664
672 if (val) 665 if (val)
673 return true; 666 return true;
@@ -677,8 +670,6 @@ static bool some_qdisc_is_running(struct net_device *dev, int lock)
677 670
678void dev_deactivate(struct net_device *dev) 671void dev_deactivate(struct net_device *dev)
679{ 672{
680 bool running;
681
682 netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); 673 netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc);
683 dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc); 674 dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc);
684 675
@@ -688,25 +679,8 @@ void dev_deactivate(struct net_device *dev)
688 synchronize_rcu(); 679 synchronize_rcu();
689 680
690 /* Wait for outstanding qdisc_run calls. */ 681 /* Wait for outstanding qdisc_run calls. */
691 do { 682 while (some_qdisc_is_busy(dev))
692 while (some_qdisc_is_running(dev, 0)) 683 yield();
693 yield();
694
695 /*
696 * Double-check inside queue lock to ensure that all effects
697 * of the queue run are visible when we return.
698 */
699 running = some_qdisc_is_running(dev, 1);
700
701 /*
702 * The running flag should never be set at this point because
703 * we've already set dev->qdisc to noop_qdisc *inside* the same
704 * pair of spin locks. That is, if any qdisc_run starts after
705 * our initial test it should see the noop_qdisc and then
706 * clear the RUNNING bit before dropping the queue lock. So
707 * if it is set here then we've found a bug.
708 */
709 } while (WARN_ON_ONCE(running));
710} 684}
711 685
712static void dev_init_scheduler_queue(struct net_device *dev, 686static void dev_init_scheduler_queue(struct net_device *dev,
@@ -735,14 +709,10 @@ static void shutdown_scheduler_queue(struct net_device *dev,
735 struct Qdisc *qdisc_default = _qdisc_default; 709 struct Qdisc *qdisc_default = _qdisc_default;
736 710
737 if (qdisc) { 711 if (qdisc) {
738 spinlock_t *root_lock = qdisc_lock(qdisc); 712 rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
739
740 dev_queue->qdisc = qdisc_default;
741 dev_queue->qdisc_sleeping = qdisc_default; 713 dev_queue->qdisc_sleeping = qdisc_default;
742 714
743 spin_lock_bh(root_lock);
744 qdisc_destroy(qdisc); 715 qdisc_destroy(qdisc);
745 spin_unlock_bh(root_lock);
746 } 716 }
747} 717}
748 718
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index c2b8d9cce3d2..c1e77da8cd09 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1045,7 +1045,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1045 1045
1046 if (tca[TCA_RATE]) 1046 if (tca[TCA_RATE])
1047 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1047 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1048 qdisc_root_lock(sch), 1048 qdisc_root_sleeping_lock(sch),
1049 tca[TCA_RATE]); 1049 tca[TCA_RATE]);
1050 return 0; 1050 return 0;
1051 } 1051 }
@@ -1104,7 +1104,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1104 1104
1105 if (tca[TCA_RATE]) 1105 if (tca[TCA_RATE])
1106 gen_new_estimator(&cl->bstats, &cl->rate_est, 1106 gen_new_estimator(&cl->bstats, &cl->rate_est,
1107 qdisc_root_lock(sch), tca[TCA_RATE]); 1107 qdisc_root_sleeping_lock(sch), tca[TCA_RATE]);
1108 *arg = (unsigned long)cl; 1108 *arg = (unsigned long)cl;
1109 return 0; 1109 return 0;
1110} 1110}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index be35422711a3..97d4761cc31e 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -577,7 +577,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
577 sch->qstats.drops++; 577 sch->qstats.drops++;
578 cl->qstats.drops++; 578 cl->qstats.drops++;
579 } 579 }
580 return NET_XMIT_DROP; 580 return ret;
581 } else { 581 } else {
582 cl->bstats.packets += 582 cl->bstats.packets +=
583 skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1; 583 skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
@@ -623,7 +623,7 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
623 sch->qstats.drops++; 623 sch->qstats.drops++;
624 cl->qstats.drops++; 624 cl->qstats.drops++;
625 } 625 }
626 return NET_XMIT_DROP; 626 return ret;
627 } else 627 } else
628 htb_activate(q, cl); 628 htb_activate(q, cl);
629 629
@@ -1279,7 +1279,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
1279 1279
1280 /* delete from hash and active; remainder in destroy_class */ 1280 /* delete from hash and active; remainder in destroy_class */
1281 qdisc_class_hash_remove(&q->clhash, &cl->common); 1281 qdisc_class_hash_remove(&q->clhash, &cl->common);
1282 cl->parent->children--; 1282 if (cl->parent)
1283 cl->parent->children--;
1283 1284
1284 if (cl->prio_activity) 1285 if (cl->prio_activity)
1285 htb_deactivate(q, cl); 1286 htb_deactivate(q, cl);
@@ -1371,7 +1372,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1371 goto failure; 1372 goto failure;
1372 1373
1373 gen_new_estimator(&cl->bstats, &cl->rate_est, 1374 gen_new_estimator(&cl->bstats, &cl->rate_est,
1374 qdisc_root_lock(sch), 1375 qdisc_root_sleeping_lock(sch),
1375 tca[TCA_RATE] ? : &est.nla); 1376 tca[TCA_RATE] ? : &est.nla);
1376 cl->refcnt = 1; 1377 cl->refcnt = 1;
1377 cl->children = 0; 1378 cl->children = 0;
@@ -1426,7 +1427,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1426 } else { 1427 } else {
1427 if (tca[TCA_RATE]) 1428 if (tca[TCA_RATE])
1428 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1429 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1429 qdisc_root_lock(sch), 1430 qdisc_root_sleeping_lock(sch),
1430 tca[TCA_RATE]); 1431 tca[TCA_RATE]);
1431 sch_tree_lock(sch); 1432 sch_tree_lock(sch);
1432 } 1433 }
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index eac197610edf..a6697c686c7f 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -113,11 +113,11 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
113 if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) { 113 if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) {
114 sch->q.qlen++; 114 sch->q.qlen++;
115 sch->qstats.requeues++; 115 sch->qstats.requeues++;
116 return 0; 116 return NET_XMIT_SUCCESS;
117 } 117 }
118 if (net_xmit_drop_count(ret)) 118 if (net_xmit_drop_count(ret))
119 sch->qstats.drops++; 119 sch->qstats.drops++;
120 return NET_XMIT_DROP; 120 return ret;
121} 121}
122 122
123 123
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 7d3b7ff3bf07..94c61598b86a 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -123,15 +123,8 @@ 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) {