aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r--net/sched/sch_api.c121
1 files changed, 82 insertions, 39 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index c25465e5607a..1122c952aa99 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>
@@ -198,19 +199,53 @@ struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
198 return NULL; 199 return NULL;
199} 200}
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
201struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) 227struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
202{ 228{
203 unsigned int i; 229 unsigned int i;
230 struct Qdisc *q;
231
232 spin_lock_bh(&qdisc_list_lock);
204 233
205 for (i = 0; i < dev->num_tx_queues; i++) { 234 for (i = 0; i < dev->num_tx_queues; i++) {
206 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 235 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
207 struct Qdisc *q, *txq_root = txq->qdisc_sleeping; 236 struct Qdisc *txq_root = txq->qdisc_sleeping;
208 237
209 q = qdisc_match_from_root(txq_root, handle); 238 q = qdisc_match_from_root(txq_root, handle);
210 if (q) 239 if (q)
211 return q; 240 goto unlock;
212 } 241 }
213 return qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle); 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;
214} 249}
215 250
216static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) 251static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
@@ -331,7 +366,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
331 if (!s || tsize != s->tsize || (!tab && tsize > 0)) 366 if (!s || tsize != s->tsize || (!tab && tsize > 0))
332 return ERR_PTR(-EINVAL); 367 return ERR_PTR(-EINVAL);
333 368
334 spin_lock_bh(&qdisc_stab_lock); 369 spin_lock(&qdisc_stab_lock);
335 370
336 list_for_each_entry(stab, &qdisc_stab_list, list) { 371 list_for_each_entry(stab, &qdisc_stab_list, list) {
337 if (memcmp(&stab->szopts, s, sizeof(*s))) 372 if (memcmp(&stab->szopts, s, sizeof(*s)))
@@ -339,11 +374,11 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
339 if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16))) 374 if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16)))
340 continue; 375 continue;
341 stab->refcnt++; 376 stab->refcnt++;
342 spin_unlock_bh(&qdisc_stab_lock); 377 spin_unlock(&qdisc_stab_lock);
343 return stab; 378 return stab;
344 } 379 }
345 380
346 spin_unlock_bh(&qdisc_stab_lock); 381 spin_unlock(&qdisc_stab_lock);
347 382
348 stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL); 383 stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL);
349 if (!stab) 384 if (!stab)
@@ -354,9 +389,9 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
354 if (tsize > 0) 389 if (tsize > 0)
355 memcpy(stab->data, tab, tsize * sizeof(u16)); 390 memcpy(stab->data, tab, tsize * sizeof(u16));
356 391
357 spin_lock_bh(&qdisc_stab_lock); 392 spin_lock(&qdisc_stab_lock);
358 list_add_tail(&stab->list, &qdisc_stab_list); 393 list_add_tail(&stab->list, &qdisc_stab_list);
359 spin_unlock_bh(&qdisc_stab_lock); 394 spin_unlock(&qdisc_stab_lock);
360 395
361 return stab; 396 return stab;
362} 397}
@@ -366,14 +401,14 @@ void qdisc_put_stab(struct qdisc_size_table *tab)
366 if (!tab) 401 if (!tab)
367 return; 402 return;
368 403
369 spin_lock_bh(&qdisc_stab_lock); 404 spin_lock(&qdisc_stab_lock);
370 405
371 if (--tab->refcnt == 0) { 406 if (--tab->refcnt == 0) {
372 list_del(&tab->list); 407 list_del(&tab->list);
373 kfree(tab); 408 kfree(tab);
374 } 409 }
375 410
376 spin_unlock_bh(&qdisc_stab_lock); 411 spin_unlock(&qdisc_stab_lock);
377} 412}
378EXPORT_SYMBOL(qdisc_put_stab); 413EXPORT_SYMBOL(qdisc_put_stab);
379 414
@@ -426,7 +461,7 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
426 461
427 wd->qdisc->flags &= ~TCQ_F_THROTTLED; 462 wd->qdisc->flags &= ~TCQ_F_THROTTLED;
428 smp_wmb(); 463 smp_wmb();
429 __netif_schedule(wd->qdisc); 464 __netif_schedule(qdisc_root(wd->qdisc));
430 465
431 return HRTIMER_NORESTART; 466 return HRTIMER_NORESTART;
432} 467}
@@ -443,6 +478,10 @@ void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
443{ 478{
444 ktime_t time; 479 ktime_t time;
445 480
481 if (test_bit(__QDISC_STATE_DEACTIVATED,
482 &qdisc_root_sleeping(wd->qdisc)->state))
483 return;
484
446 wd->qdisc->flags |= TCQ_F_THROTTLED; 485 wd->qdisc->flags |= TCQ_F_THROTTLED;
447 time = ktime_set(0, 0); 486 time = ktime_set(0, 0);
448 time = ktime_add_ns(time, PSCHED_US2NS(expires)); 487 time = ktime_add_ns(time, PSCHED_US2NS(expires));
@@ -585,7 +624,7 @@ static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
585 struct Qdisc *oqdisc = dev_queue->qdisc_sleeping; 624 struct Qdisc *oqdisc = dev_queue->qdisc_sleeping;
586 spinlock_t *root_lock; 625 spinlock_t *root_lock;
587 626
588 root_lock = qdisc_root_lock(oqdisc); 627 root_lock = qdisc_lock(oqdisc);
589 spin_lock_bh(root_lock); 628 spin_lock_bh(root_lock);
590 629
591 /* Prune old scheduler */ 630 /* Prune old scheduler */
@@ -596,7 +635,7 @@ static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
596 if (qdisc == NULL) 635 if (qdisc == NULL)
597 qdisc = &noop_qdisc; 636 qdisc = &noop_qdisc;
598 dev_queue->qdisc_sleeping = qdisc; 637 dev_queue->qdisc_sleeping = qdisc;
599 dev_queue->qdisc = &noop_qdisc; 638 rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc);
600 639
601 spin_unlock_bh(root_lock); 640 spin_unlock_bh(root_lock);
602 641
@@ -637,11 +676,8 @@ static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid
637 if (new || old) 676 if (new || old)
638 qdisc_notify(skb, n, clid, old, new); 677 qdisc_notify(skb, n, clid, old, new);
639 678
640 if (old) { 679 if (old)
641 spin_lock_bh(&old->q.lock);
642 qdisc_destroy(old); 680 qdisc_destroy(old);
643 spin_unlock_bh(&old->q.lock);
644 }
645} 681}
646 682
647/* Graft qdisc "new" to class "classid" of qdisc "parent" or 683/* Graft qdisc "new" to class "classid" of qdisc "parent" or
@@ -707,6 +743,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
707 return err; 743 return err;
708} 744}
709 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
710/* 750/*
711 Allocate and initialize new qdisc. 751 Allocate and initialize new qdisc.
712 752
@@ -767,6 +807,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
767 if (handle == TC_H_INGRESS) { 807 if (handle == TC_H_INGRESS) {
768 sch->flags |= TCQ_F_INGRESS; 808 sch->flags |= TCQ_F_INGRESS;
769 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);
770 } else { 811 } else {
771 if (handle == 0) { 812 if (handle == 0) {
772 handle = qdisc_alloc_handle(dev); 813 handle = qdisc_alloc_handle(dev);
@@ -774,6 +815,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
774 if (handle == 0) 815 if (handle == 0)
775 goto err_out3; 816 goto err_out3;
776 } 817 }
818 lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
777 } 819 }
778 820
779 sch->handle = handle; 821 sch->handle = handle;
@@ -788,9 +830,16 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
788 sch->stab = stab; 830 sch->stab = stab;
789 } 831 }
790 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
791 err = gen_new_estimator(&sch->bstats, &sch->rate_est, 841 err = gen_new_estimator(&sch->bstats, &sch->rate_est,
792 qdisc_root_lock(sch), 842 root_lock, tca[TCA_RATE]);
793 tca[TCA_RATE]);
794 if (err) { 843 if (err) {
795 /* 844 /*
796 * Any broken qdiscs that would require 845 * Any broken qdiscs that would require
@@ -802,8 +851,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
802 goto err_out3; 851 goto err_out3;
803 } 852 }
804 } 853 }
805 if ((parent != TC_H_ROOT) && !(sch->flags & TCQ_F_INGRESS)) 854
806 list_add_tail(&sch->list, &dev_queue->qdisc_sleeping->list); 855 qdisc_list_add(sch);
807 856
808 return sch; 857 return sch;
809 } 858 }
@@ -842,7 +891,8 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
842 891
843 if (tca[TCA_RATE]) 892 if (tca[TCA_RATE])
844 gen_replace_estimator(&sch->bstats, &sch->rate_est, 893 gen_replace_estimator(&sch->bstats, &sch->rate_est,
845 qdisc_root_lock(sch), tca[TCA_RATE]); 894 qdisc_root_sleeping_lock(sch),
895 tca[TCA_RATE]);
846 return 0; 896 return 0;
847} 897}
848 898
@@ -1084,20 +1134,13 @@ create_n_graft:
1084 } 1134 }
1085 1135
1086graft: 1136graft:
1087 if (1) { 1137 err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
1088 spinlock_t *root_lock; 1138 if (err) {
1089 1139 if (q)
1090 err = qdisc_graft(dev, p, skb, n, clid, q, NULL); 1140 qdisc_destroy(q);
1091 if (err) { 1141 return err;
1092 if (q) {
1093 root_lock = qdisc_root_lock(q);
1094 spin_lock_bh(root_lock);
1095 qdisc_destroy(q);
1096 spin_unlock_bh(root_lock);
1097 }
1098 return err;
1099 }
1100 } 1142 }
1143
1101 return 0; 1144 return 0;
1102} 1145}
1103 1146
@@ -1126,8 +1169,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
1126 if (q->stab && qdisc_dump_stab(skb, q->stab) < 0) 1169 if (q->stab && qdisc_dump_stab(skb, q->stab) < 0)
1127 goto nla_put_failure; 1170 goto nla_put_failure;
1128 1171
1129 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1172 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS,
1130 TCA_XSTATS, qdisc_root_lock(q), &d) < 0) 1173 qdisc_root_sleeping_lock(q), &d) < 0)
1131 goto nla_put_failure; 1174 goto nla_put_failure;
1132 1175
1133 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) 1176 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0)
@@ -1418,8 +1461,8 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
1418 if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0) 1461 if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0)
1419 goto nla_put_failure; 1462 goto nla_put_failure;
1420 1463
1421 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1464 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS,
1422 TCA_XSTATS, qdisc_root_lock(q), &d) < 0) 1465 qdisc_root_sleeping_lock(q), &d) < 0)
1423 goto nla_put_failure; 1466 goto nla_put_failure;
1424 1467
1425 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) 1468 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0)