]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
slab: Make slub local_(try)lock more precise for LOCKDEP
authorAlexei Starovoitov <ast@kernel.org>
Tue, 9 Sep 2025 01:00:05 +0000 (18:00 -0700)
committerVlastimil Babka <vbabka@suse.cz>
Mon, 29 Sep 2025 07:42:36 +0000 (09:42 +0200)
commit83382af9ddc3cb0ef43f67d049b461720ad785e6
tree590478f30d718084f7bead7e896ca56ea9b23be1
parentd7242af8643409aae32243450341ef25b28d8a8c
slab: Make slub local_(try)lock more precise for LOCKDEP

kmalloc_nolock() can be called from any context
the ___slab_alloc() can acquire local_trylock_t (which is rt_spin_lock
in PREEMPT_RT) and attempt to acquire a different local_trylock_t
while in the same task context.

The calling sequence might look like:
kmalloc() -> tracepoint -> bpf -> kmalloc_nolock()

or more precisely:
__lock_acquire+0x12ad/0x2590
lock_acquire+0x133/0x2d0
rt_spin_lock+0x6f/0x250
___slab_alloc+0xb7/0xec0
kmalloc_nolock_noprof+0x15a/0x430
my_debug_callback+0x20e/0x390 [testmod]
___slab_alloc+0x256/0xec0
__kmalloc_cache_noprof+0xd6/0x3b0

Make LOCKDEP understand that local_trylock_t-s protect
different kmem_caches. In order to do that add lock_class_key
for each kmem_cache and use that key in local_trylock_t.

This stack trace is possible on both PREEMPT_RT and !PREEMPT_RT,
but teach lockdep about it only for PREEMPT_RT, since
in !PREEMPT_RT the ___slab_alloc() code is using
local_trylock_irqsave() when lockdep is on.

Note, this patch applies this logic to local_lock_t
while the next one converts it to local_trylock_t.
Both are mapped to rt_spin_lock in PREEMPT_RT.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
mm/slab.h
mm/slub.c