summaryrefslogtreecommitdiff
path: root/include/linux/debugobjects.h
diff options
context:
space:
mode:
authorVictor Nogueira <victor@mojatatu.com>2026-09-18 10:51:57 -0300
committerJakub Kicinski <kuba@kernel.org>2026-09-21 17:31:00 -0700
commit1b4efa0399f549d9b9bf82b3e2450e10a06d65b8 (patch)
tree145cc8e20d5c8cba32bedb07739c284e41cd495d /include/linux/debugobjects.h
parent114bd09838ac6954baaf110aebc4d5503057f88a (diff)
net/sched: Avoid quadratic handle scan in qdisc_alloc_handle
qdisc_alloc_handle scans for a free auto-handle by probing the per-device qdisc hash one handle at a time. With the 16-bucket hash populated by tens of thousands of qdiscs, the failing scan is O(N^2) under rtnl_lock. A single failing add then holds rtnl_lock for most of a second, and rtnl_lock is global, so all other netlink configuration is blocked for that time. First try the handle after the rotating cursor with one qdisc_lookup, as the first iteration of the current loop does; that handle is normally free. Only when it is taken, build a bitmap of the occupied auto-handle majors in one pass over the hash and pick the first free major from the cursor. The scan is cyclic over all 0x7FFF majors starting from the same autohandle + 1 position as the current loop, so it returns the same handle for the same device state and fails only when all 0x7FFF majors are taken. The root qdisc is seeded separately because qdisc_hash_add skips parent == TC_H_ROOT. When the next handle is free, only the single qdisc_lookup of the current loop's first iteration runs; when it is taken, one O(N) walk follows. Measured as tc wall time on a defconfig kernel in a 2-vCPU guest, with an HTB root holding 32768 classes and all 32767 auto-handles in use (a no-op tc command takes 5-6.5 ms): unpatched patched failing add, space exhausted 613-749 ms 8-10 ms add after a mid-range delete 572-573 ms 9 ms The failure path returns -ENOMEM (bitmap allocation) or -ENOSPC (space exhausted) through a handle out-parameter instead of the overloaded 0 return. Since either error is now possible, the extack message changes from "Maximum number of qdisc handles was exceeded" to "Failed to allocate a qdisc handle". Reported-by: Vega <vega@nebusec.ai> Co-developed-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Victor Nogueira <victor@mojatatu.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260918135157.163015-1-victor@mojatatu.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/linux/debugobjects.h')
0 files changed, 0 insertions, 0 deletions