diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-01-12 05:01:12 -0500 |
commit | 1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch) | |
tree | 44db563f64cf5f8d62af8f99a61e2b248c44ea3a /net/sched/sch_api.c | |
parent | 03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff) | |
parent | f9eccf24615672896dc13251410c3f2f33a14f95 (diff) |
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano:
- Fix the vt8500 timer leading to a system lock up when dealing with too
small delta (Roman Volkov)
- Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST
(Daniel Lezcano)
- Prevent to compile timers using the 'iomem' API when the architecture has
not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index f43c8f33f09e..b5c2cf2aa6d4 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -253,7 +253,8 @@ int qdisc_set_default(const char *name) | |||
253 | } | 253 | } |
254 | 254 | ||
255 | /* We know handle. Find qdisc among all qdisc's attached to device | 255 | /* We know handle. Find qdisc among all qdisc's attached to device |
256 | (root qdisc, all its children, children of children etc.) | 256 | * (root qdisc, all its children, children of children etc.) |
257 | * Note: caller either uses rtnl or rcu_read_lock() | ||
257 | */ | 258 | */ |
258 | 259 | ||
259 | static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) | 260 | static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) |
@@ -264,7 +265,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) | |||
264 | root->handle == handle) | 265 | root->handle == handle) |
265 | return root; | 266 | return root; |
266 | 267 | ||
267 | list_for_each_entry(q, &root->list, list) { | 268 | list_for_each_entry_rcu(q, &root->list, list) { |
268 | if (q->handle == handle) | 269 | if (q->handle == handle) |
269 | return q; | 270 | return q; |
270 | } | 271 | } |
@@ -277,15 +278,18 @@ void qdisc_list_add(struct Qdisc *q) | |||
277 | struct Qdisc *root = qdisc_dev(q)->qdisc; | 278 | struct Qdisc *root = qdisc_dev(q)->qdisc; |
278 | 279 | ||
279 | WARN_ON_ONCE(root == &noop_qdisc); | 280 | WARN_ON_ONCE(root == &noop_qdisc); |
280 | list_add_tail(&q->list, &root->list); | 281 | ASSERT_RTNL(); |
282 | list_add_tail_rcu(&q->list, &root->list); | ||
281 | } | 283 | } |
282 | } | 284 | } |
283 | EXPORT_SYMBOL(qdisc_list_add); | 285 | EXPORT_SYMBOL(qdisc_list_add); |
284 | 286 | ||
285 | void qdisc_list_del(struct Qdisc *q) | 287 | void qdisc_list_del(struct Qdisc *q) |
286 | { | 288 | { |
287 | if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) | 289 | if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) { |
288 | list_del(&q->list); | 290 | ASSERT_RTNL(); |
291 | list_del_rcu(&q->list); | ||
292 | } | ||
289 | } | 293 | } |
290 | EXPORT_SYMBOL(qdisc_list_del); | 294 | EXPORT_SYMBOL(qdisc_list_del); |
291 | 295 | ||
@@ -750,14 +754,18 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) | |||
750 | if (n == 0) | 754 | if (n == 0) |
751 | return; | 755 | return; |
752 | drops = max_t(int, n, 0); | 756 | drops = max_t(int, n, 0); |
757 | rcu_read_lock(); | ||
753 | while ((parentid = sch->parent)) { | 758 | while ((parentid = sch->parent)) { |
754 | if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) | 759 | if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) |
755 | return; | 760 | break; |
756 | 761 | ||
762 | if (sch->flags & TCQ_F_NOPARENT) | ||
763 | break; | ||
764 | /* TODO: perform the search on a per txq basis */ | ||
757 | sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); | 765 | sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); |
758 | if (sch == NULL) { | 766 | if (sch == NULL) { |
759 | WARN_ON(parentid != TC_H_ROOT); | 767 | WARN_ON_ONCE(parentid != TC_H_ROOT); |
760 | return; | 768 | break; |
761 | } | 769 | } |
762 | cops = sch->ops->cl_ops; | 770 | cops = sch->ops->cl_ops; |
763 | if (cops->qlen_notify) { | 771 | if (cops->qlen_notify) { |
@@ -768,6 +776,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) | |||
768 | sch->q.qlen -= n; | 776 | sch->q.qlen -= n; |
769 | __qdisc_qstats_drop(sch, drops); | 777 | __qdisc_qstats_drop(sch, drops); |
770 | } | 778 | } |
779 | rcu_read_unlock(); | ||
771 | } | 780 | } |
772 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); | 781 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); |
773 | 782 | ||