summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavide Caratti <dcaratti@redhat.com>2026-02-04 17:02:31 +0100
committerJakub Kicinski <kuba@kernel.org>2026-02-05 09:32:45 -0800
commita90f6dcefca6d5ad765435b3188a3a440ed193a1 (patch)
tree7ff7e526431531309b2e72889faf040456f3ab2a /include
parent7e7fcfb0798a038b31fa3825734b5194c46b3e86 (diff)
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>
Diffstat (limited to 'include')
-rw-r--r--include/net/pkt_sched.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index e703c507d0da..18a419cd9d94 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -308,4 +308,28 @@ static inline unsigned int qdisc_peek_len(struct Qdisc *sch)
return len;
}
+static inline void qdisc_lock_init(struct Qdisc *sch,
+ const struct Qdisc_ops *ops)
+{
+ spin_lock_init(&sch->q.lock);
+
+ /* Skip dynamic keys if nesting is not possible */
+ if (ops->static_flags & TCQ_F_INGRESS ||
+ ops == &noqueue_qdisc_ops)
+ return;
+
+ lockdep_register_key(&sch->root_lock_key);
+ lockdep_set_class(&sch->q.lock, &sch->root_lock_key);
+}
+
+static inline void qdisc_lock_uninit(struct Qdisc *sch,
+ const struct Qdisc_ops *ops)
+{
+ if (ops->static_flags & TCQ_F_INGRESS ||
+ ops == &noqueue_qdisc_ops)
+ return;
+
+ lockdep_unregister_key(&sch->root_lock_key);
+}
+
#endif