Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pkt_sched: Fix locking of qdisc_root with qdisc_root_sleeping_lock()

Use qdisc_root_sleeping_lock() instead of qdisc_root_lock() where
appropriate. The only difference is while dev is deactivated, when
currently we can use a sleeping qdisc with the lock of noop_qdisc.
This shouldn't be dangerous since after deactivation root lock could
be used only by gen_estimator code, but looks wrong anyway.

Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jarek Poplawski and committed by
David S. Miller
102396ae 3cc76caa

+11 -11
+1 -1
net/sched/cls_api.c
··· 205 205 } 206 206 } 207 207 208 - root_lock = qdisc_root_lock(q); 208 + root_lock = qdisc_root_sleeping_lock(q); 209 209 210 210 if (tp == NULL) { 211 211 /* Proto-tcf does not exist, create new one */
+1 -1
net/sched/cls_route.c
··· 75 75 static inline 76 76 void route4_reset_fastmap(struct Qdisc *q, struct route4_head *head, u32 id) 77 77 { 78 - spinlock_t *root_lock = qdisc_root_lock(q); 78 + spinlock_t *root_lock = qdisc_root_sleeping_lock(q); 79 79 80 80 spin_lock_bh(root_lock); 81 81 memset(head->fastmap, 0, sizeof(head->fastmap));
+4 -4
net/sched/sch_api.c
··· 1169 1169 if (q->stab && qdisc_dump_stab(skb, q->stab) < 0) 1170 1170 goto nla_put_failure; 1171 1171 1172 - if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1173 - TCA_XSTATS, qdisc_root_lock(q), &d) < 0) 1172 + if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, 1173 + qdisc_root_sleeping_lock(q), &d) < 0) 1174 1174 goto nla_put_failure; 1175 1175 1176 1176 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) ··· 1461 1461 if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0) 1462 1462 goto nla_put_failure; 1463 1463 1464 - if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1465 - TCA_XSTATS, qdisc_root_lock(q), &d) < 0) 1464 + if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS, 1465 + qdisc_root_sleeping_lock(q), &d) < 0) 1466 1466 goto nla_put_failure; 1467 1467 1468 1468 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0)
+1 -1
net/sched/sch_cbq.c
··· 1754 1754 1755 1755 if (--cl->refcnt == 0) { 1756 1756 #ifdef CONFIG_NET_CLS_ACT 1757 - spinlock_t *root_lock = qdisc_root_lock(sch); 1757 + spinlock_t *root_lock = qdisc_root_sleeping_lock(sch); 1758 1758 struct cbq_sched_data *q = qdisc_priv(sch); 1759 1759 1760 1760 spin_lock_bh(root_lock);
+2 -2
net/sched/sch_htb.c
··· 1043 1043 1044 1044 static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) 1045 1045 { 1046 - spinlock_t *root_lock = qdisc_root_lock(sch); 1046 + spinlock_t *root_lock = qdisc_root_sleeping_lock(sch); 1047 1047 struct htb_sched *q = qdisc_priv(sch); 1048 1048 struct nlattr *nest; 1049 1049 struct tc_htb_glob gopt; ··· 1075 1075 struct sk_buff *skb, struct tcmsg *tcm) 1076 1076 { 1077 1077 struct htb_class *cl = (struct htb_class *)arg; 1078 - spinlock_t *root_lock = qdisc_root_lock(sch); 1078 + spinlock_t *root_lock = qdisc_root_sleeping_lock(sch); 1079 1079 struct nlattr *nest; 1080 1080 struct tc_htb_opt opt; 1081 1081
+1 -1
net/sched/sch_netem.c
··· 341 341 for (i = 0; i < n; i++) 342 342 d->table[i] = data[i]; 343 343 344 - root_lock = qdisc_root_lock(sch); 344 + root_lock = qdisc_root_sleeping_lock(sch); 345 345 346 346 spin_lock_bh(root_lock); 347 347 d = xchg(&q->delay_dist, d);
+1 -1
net/sched/sch_teql.c
··· 161 161 txq = netdev_get_tx_queue(master->dev, 0); 162 162 master->slaves = NULL; 163 163 164 - root_lock = qdisc_root_lock(txq->qdisc); 164 + root_lock = qdisc_root_sleeping_lock(txq->qdisc); 165 165 spin_lock_bh(root_lock); 166 166 qdisc_reset(txq->qdisc); 167 167 spin_unlock_bh(root_lock);