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

Configure Feed

Select the types of activity you want to include in your feed.

net/sched: don't use dynamic lockdep keys with clsact/ingress/noqueue

Currently we are registering one dynamic lockdep key for each allocated
qdisc, to avoid false deadlock reports when mirred (or TC eBPF) redirects
packets to another device while the root lock is acquired [1].
Since dynamic keys are a limited resource, we can save them at least for
qdiscs that are not meant to acquire the root lock in the traffic path,
or to carry traffic at all, like:

- clsact
- ingress
- noqueue

Don't register dynamic keys for the above schedulers, so that we hit
MAX_LOCKDEP_KEYS later in our tests.

[1] https://github.com/multipath-tcp/mptcp_net-next/issues/451

Changes in v2:
- change ordering of spin_lock_init() vs. lockdep_register_key()
(Jakub Kicinski)

Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Link: https://patch.msgid.link/94448f7fa7c4f52d2ce416a4895ec87d456d7417.1770220576.git.dcaratti@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Davide Caratti and committed by
Jakub Kicinski
a90f6dce 7e7fcfb0

+28 -6
+24
include/net/pkt_sched.h
··· 308 308 return len; 309 309 } 310 310 311 + static inline void qdisc_lock_init(struct Qdisc *sch, 312 + const struct Qdisc_ops *ops) 313 + { 314 + spin_lock_init(&sch->q.lock); 315 + 316 + /* Skip dynamic keys if nesting is not possible */ 317 + if (ops->static_flags & TCQ_F_INGRESS || 318 + ops == &noqueue_qdisc_ops) 319 + return; 320 + 321 + lockdep_register_key(&sch->root_lock_key); 322 + lockdep_set_class(&sch->q.lock, &sch->root_lock_key); 323 + } 324 + 325 + static inline void qdisc_lock_uninit(struct Qdisc *sch, 326 + const struct Qdisc_ops *ops) 327 + { 328 + if (ops->static_flags & TCQ_F_INGRESS || 329 + ops == &noqueue_qdisc_ops) 330 + return; 331 + 332 + lockdep_unregister_key(&sch->root_lock_key); 333 + } 334 + 311 335 #endif
+1 -1
net/sched/sch_api.c
··· 1353 1353 ops->destroy(sch); 1354 1354 qdisc_put_stab(rtnl_dereference(sch->stab)); 1355 1355 err_out3: 1356 - lockdep_unregister_key(&sch->root_lock_key); 1356 + qdisc_lock_uninit(sch, ops); 1357 1357 netdev_put(dev, &sch->dev_tracker); 1358 1358 qdisc_free(sch); 1359 1359 err_out2:
+3 -5
net/sched/sch_generic.c
··· 955 955 __skb_queue_head_init(&sch->gso_skb); 956 956 __skb_queue_head_init(&sch->skb_bad_txq); 957 957 gnet_stats_basic_sync_init(&sch->bstats); 958 - lockdep_register_key(&sch->root_lock_key); 959 - spin_lock_init(&sch->q.lock); 960 - lockdep_set_class(&sch->q.lock, &sch->root_lock_key); 958 + qdisc_lock_init(sch, ops); 961 959 962 960 if (ops->static_flags & TCQ_F_CPUSTATS) { 963 961 sch->cpu_bstats = ··· 985 987 986 988 return sch; 987 989 errout1: 988 - lockdep_unregister_key(&sch->root_lock_key); 990 + qdisc_lock_uninit(sch, ops); 989 991 kfree(sch); 990 992 errout: 991 993 return ERR_PTR(err); ··· 1074 1076 if (ops->destroy) 1075 1077 ops->destroy(qdisc); 1076 1078 1077 - lockdep_unregister_key(&qdisc->root_lock_key); 1079 + qdisc_lock_uninit(qdisc, ops); 1078 1080 bpf_module_put(ops, ops->owner); 1079 1081 netdev_put(dev, &qdisc->dev_tracker); 1080 1082