[PATCH 1/2] mm/slub: preserve no-lock freeing after memcg charge failure

From: Karl Mehltretter

Date: Thu Oct 01 2026 - 00:42:31 EST


kmalloc_nolock() can obtain an object before its memcg
post-allocation charge fails. For a single object,
memcg_slab_post_alloc_hook() rolls the allocation back through
memcg_alloc_abort_single(). That enters the regular SLUB free path,
which can take a sleeping list_lock on PREEMPT_RT even though the caller
selected a no-lock allocation.

Use kfree_nolock() when the allocation flags disallow spinning. This
keeps the SLUB object rollback on the no-lock free path. The failed
allocation continues to return NULL.

Fixes: af92793e52c3 ("slab: Introduce kmalloc_nolock() and kfree_nolock().")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
---
mm/slub.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/mm/slub.c b/mm/slub.c
index 54ec125033571..a1f08338102e2 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2519,7 +2519,10 @@ bool memcg_slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags,
return true;

if (likely(size == 1)) {
- memcg_alloc_abort_single(s, *p);
+ if (alloc_flags_allow_spinning(ac->alloc_flags))
+ memcg_alloc_abort_single(s, *p);
+ else
+ kfree_nolock(*p);
*p = NULL;
} else {
kmem_cache_free_bulk(s, size, p);
--
2.53.0