Skip to content

Commit c379b74

Browse files
committed
slab: prevent infinite loop in kmalloc_nolock() with debugging
In review of a followup work, Harry noticed a potential infinite loop. Upon closed inspection, it already exists for kmalloc_nolock() on a cache with debugging enabled, since commit af92793 ("slab: Introduce kmalloc_nolock() and kfree_nolock().") When alloc_single_from_new_slab() fails to trylock node list_lock, we keep retrying to get partial slab or allocate a new slab. If we indeed interrupted somebody holding the list_lock, the trylock fill fail deterministically and we end up allocating and defer-freeing slabs indefinitely with no progress. To fix it, fail the allocation if spinning is not allowed. This is acceptable in the restricted context of kmalloc_nolock(), especially with debugging enabled. Reported-by: Harry Yoo <harry.yoo@oracle.com> Closes: https://lore.kernel.org/all/aQLqZjjq1SPD3Fml@hyeyoo/ Fixes: af92793 ("slab: Introduce kmalloc_nolock() and kfree_nolock().") Acked-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Harry Yoo <harry.yoo@oracle.com> Link: https://patch.msgid.link/20251103-fix-nolock-loop-v1-1-6e2b3e82b9da@suse.cz Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
1 parent 7f434e1 commit c379b74

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

mm/slub.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4666,8 +4666,12 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
46664666
if (kmem_cache_debug(s)) {
46674667
freelist = alloc_single_from_new_slab(s, slab, orig_size, gfpflags);
46684668

4669-
if (unlikely(!freelist))
4669+
if (unlikely(!freelist)) {
4670+
/* This could cause an endless loop. Fail instead. */
4671+
if (!allow_spin)
4672+
return NULL;
46704673
goto new_objects;
4674+
}
46714675

46724676
if (s->flags & SLAB_STORE_USER)
46734677
set_track(s, freelist, TRACK_ALLOC, addr,

0 commit comments

Comments
 (0)