]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/slab: replace __GFP_NO_OBJ_EXT with SLAB_ALLOC_NO_RECURSE for sheaves
authorVlastimil Babka (SUSE) <vbabka@kernel.org>
Thu, 11 Jun 2026 16:24:06 +0000 (18:24 +0200)
committerVlastimil Babka (SUSE) <vbabka@kernel.org>
Thu, 18 Jun 2026 08:40:53 +0000 (10:40 +0200)
Finish the switch away from __GFP_NO_OBJ_EXT by replacing it with
SLAB_ALLOC_NO_RECURSE when allocating empty sheaves. Pass alloc_flags to
[__]alloc_empty_sheaf(). Callers that can't be part of a recursive
kmalloc() chain simply pass SLAB_ALLOC_DEFAULT. Use kmalloc_flags()
instead of kzalloc() for allocating the sheaf.

With that we can finalize the removal the __GFP_NO_OBJ_EXT handling from
obj_ext allocations as well, leaving only SLAB_ALLOC_NO_RECURSE in
place.

This leaves __GFP_NO_OBJ_EXT with no users in slab, so stop allowing the
flag in kmalloc_nolock().

Link: https://patch.msgid.link/20260610-slab_alloc_flags-v2-16-7190909db118@kernel.org
Reviewed-by: Hao Li <hao.li@linux.dev>
Reviewed-by: Harry Yoo (Oracle) <harry@kernel.org>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
include/linux/slab.h
mm/slub.c

index b955f3cbb7328f4ec75758b8424a388b57df78c5..43c3d9b51107e308b94ea1c54333eea419bcfe2c 100644 (file)
@@ -1039,9 +1039,9 @@ void *_kmalloc_nolock_noprof(DECL_TOKEN_PARAMS(size, token), gfp_t gfp_flags, in
 /**
  * kmalloc_nolock - Allocate an object of given size from any context.
  * @size: size to allocate
- * @gfp_flags: GFP flags. Only __GFP_ACCOUNT, __GFP_ZERO, __GFP_NO_OBJ_EXT
- * allowed. Also __GFP_NOWARN and __GFP_NOMEMALLOC are allowed but added
- * internally thus not necessary.
+ * @gfp_flags: GFP flags. Only __GFP_ACCOUNT and __GFP_ZERO allowed.  Also
+ * __GFP_NOWARN and __GFP_NOMEMALLOC are allowed but added internally thus not
+ * necessary.
  * @node: node number of the target node.
  *
  * Return: pointer to the new object or NULL in case of error.
index dc4b4ae874ce77921aed5a178b332830e8c6e3f1..917635203f7371fc5a314e08cb8ec0254ece4768 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2172,7 +2172,6 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
 
        gfp &= ~OBJCGS_CLEAR_MASK;
        /* Prevent recursive extension vector allocation */
-       gfp |= __GFP_NO_OBJ_EXT;
        alloc_flags |= SLAB_ALLOC_NO_RECURSE;
        alloc_flags &= ~SLAB_ALLOC_NEW_SLAB;
 
@@ -2378,7 +2377,7 @@ __alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags,
        if (s->flags & (SLAB_NO_OBJ_EXT | SLAB_NOLEAKTRACE))
                return;
 
-       if (alloc_flags & SLAB_ALLOC_NO_RECURSE || flags & __GFP_NO_OBJ_EXT)
+       if (alloc_flags & SLAB_ALLOC_NO_RECURSE)
                return;
 
        slab = virt_to_slab(object);
@@ -2763,7 +2762,7 @@ static inline void *setup_object(struct kmem_cache *s, void *object)
 }
 
 static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp,
-                                             unsigned int capacity)
+                               unsigned int alloc_flags, unsigned int capacity)
 {
        struct slab_sheaf *sheaf;
        size_t sheaf_size;
@@ -2774,10 +2773,10 @@ static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp,
         * bucket)
         */
        if (s->flags & SLAB_KMALLOC)
-               gfp |= __GFP_NO_OBJ_EXT;
+               alloc_flags |= SLAB_ALLOC_NO_RECURSE;
 
        sheaf_size = struct_size(sheaf, objects, capacity);
-       sheaf = kzalloc(sheaf_size, gfp);
+       sheaf = kmalloc_flags(sheaf_size, gfp | __GFP_ZERO, alloc_flags, NUMA_NO_NODE);
 
        if (unlikely(!sheaf))
                return NULL;
@@ -2790,20 +2789,20 @@ static struct slab_sheaf *__alloc_empty_sheaf(struct kmem_cache *s, gfp_t gfp,
 }
 
 static inline struct slab_sheaf *alloc_empty_sheaf(struct kmem_cache *s,
-                                                  gfp_t gfp)
+                               gfp_t gfp, unsigned int alloc_flags)
 {
-       if (gfp & __GFP_NO_OBJ_EXT)
+       if (alloc_flags & SLAB_ALLOC_NO_RECURSE)
                return NULL;
 
        gfp &= ~OBJCGS_CLEAR_MASK;
 
-       return __alloc_empty_sheaf(s, gfp, s->sheaf_capacity);
+       return __alloc_empty_sheaf(s, gfp, alloc_flags, s->sheaf_capacity);
 }
 
 static void free_empty_sheaf(struct kmem_cache *s, struct slab_sheaf *sheaf)
 {
        /*
-        * If the sheaf was created with __GFP_NO_OBJ_EXT flag then its
+        * If the sheaf was created with SLAB_ALLOC_NO_RECURSE flag then its
         * corresponding extension is NULL and alloc_tag_sub() will throw a
         * warning, therefore replace NULL with CODETAG_EMPTY to indicate
         * that the extension for this sheaf is expected to be NULL.
@@ -4695,7 +4694,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs,
                return NULL;
 
        if (!empty) {
-               empty = alloc_empty_sheaf(s, gfp);
+               empty = alloc_empty_sheaf(s, gfp, alloc_flags);
                if (!empty)
                        return NULL;
        }
@@ -5068,7 +5067,7 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
 
        if (unlikely(size > s->sheaf_capacity)) {
 
-               sheaf = __alloc_empty_sheaf(s, gfp, size);
+               sheaf = __alloc_empty_sheaf(s, gfp, SLAB_ALLOC_DEFAULT, size);
                if (!sheaf)
                        return NULL;
 
@@ -5113,7 +5112,7 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size)
 
 
        if (!sheaf)
-               sheaf = alloc_empty_sheaf(s, gfp);
+               sheaf = alloc_empty_sheaf(s, gfp, SLAB_ALLOC_DEFAULT);
 
        if (sheaf) {
                sheaf->capacity = s->sheaf_capacity;
@@ -5398,7 +5397,7 @@ static void *__kmalloc_nolock_noprof(DECL_TOKEN_PARAMS(size, token), gfp_t gfp_f
 
        VM_WARN_ON_ONCE(alloc_flags_allow_spinning(ac->alloc_flags));
        VM_WARN_ON_ONCE(gfp_flags & ~(__GFP_ACCOUNT | __GFP_ZERO |
-                       __GFP_NO_OBJ_EXT | __GFP_NOWARN | __GFP_NOMEMALLOC));
+                                     __GFP_NOWARN | __GFP_NOMEMALLOC));
 
        gfp_flags |= __GFP_NOWARN | __GFP_NOMEMALLOC;
 
@@ -5913,7 +5912,7 @@ alloc_empty:
        if (!allow_spin)
                return NULL;
 
-       empty = alloc_empty_sheaf(s, GFP_NOWAIT);
+       empty = alloc_empty_sheaf(s, GFP_NOWAIT, SLAB_ALLOC_DEFAULT);
        if (empty)
                goto got_empty;
 
@@ -6097,7 +6096,7 @@ bool __kfree_rcu_sheaf(struct kmem_cache *s, void *obj)
 
                local_unlock(&s->cpu_sheaves->lock);
 
-               empty = alloc_empty_sheaf(s, GFP_NOWAIT);
+               empty = alloc_empty_sheaf(s, GFP_NOWAIT, SLAB_ALLOC_DEFAULT);
 
                if (!empty)
                        goto fail;
@@ -7642,7 +7641,7 @@ static int init_percpu_sheaves(struct kmem_cache *s)
                if (!s->sheaf_capacity)
                        pcs->main = &bootstrap_sheaf;
                else
-                       pcs->main = alloc_empty_sheaf(s, GFP_KERNEL);
+                       pcs->main = alloc_empty_sheaf(s, GFP_KERNEL, SLAB_ALLOC_DEFAULT);
 
                if (!pcs->main)
                        return -ENOMEM;
@@ -8508,7 +8507,8 @@ static void __init bootstrap_cache_sheaves(struct kmem_cache *s)
 
                pcs = per_cpu_ptr(s->cpu_sheaves, cpu);
 
-               pcs->main = __alloc_empty_sheaf(s, GFP_KERNEL, capacity);
+               pcs->main = __alloc_empty_sheaf(s, GFP_KERNEL,
+                               SLAB_ALLOC_DEFAULT, capacity);
 
                if (!pcs->main) {
                        failed = true;