Re: [PATCH RFC 09/12] mm/slab: introduce slab_obj_ext_has_codetag()

From: Suren Baghdasaryan

Date: Thu Jul 16 2026 - 00:26:03 EST


On Wed, Jul 15, 2026 at 3:11 AM Vlastimil Babka (SUSE)
<vbabka@xxxxxxxxxx> wrote:
>
> mem_alloc_profiling_enabled() allows evaluating (with a static key) if
> memory profiling is currently enabled. mem_profiling_support is a
> variable where false means it's not possible to enable it anymore,
> because the system was booted with "never" or it was later shut down.
> This is possible to query by mem_alloc_profiling_permanently_disabled().
>
> To make slabobj_ext array size handling dynamic, we need a snapshot of
> mem_alloc_profiling_permanently_disabled() early in boot, so that's not
> affected by a later shutdown. We also need it to be static key based for
> performance. Neither mem_alloc_profiling_enabled() nor
> mem_alloc_profiling_permanently_disabled() satisfy this.
>
> Therefore introduce slab_obj_ext_has_codetag() with an underlying static
> key for that use case. Its state is made to reflect the result of
> mem_alloc_profiling_permanently_disabled() during kmem_cache_init(),
> which does happen after setup_early_mem_profiling().
>
> Signed-off-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>

Reviewed-by: Suren Baghdasaryan <surenb@xxxxxxxxxx>

> ---
> mm/slab.h | 16 ++++++++++++++++
> mm/slub.c | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 47 insertions(+)
>
> diff --git a/mm/slab.h b/mm/slab.h
> index 359ab8caf61e..dcca86799fc9 100644
> --- a/mm/slab.h
> +++ b/mm/slab.h
> @@ -564,6 +564,22 @@ struct slabobj_ext {
> };
> } __aligned(8);
>
> +#ifdef CONFIG_MEM_ALLOC_PROFILING
> +DECLARE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
> + slab_obj_ext_has_codetag_key);
> +
> +static inline bool slab_obj_ext_has_codetag(void)
> +{
> + return static_branch_maybe(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
> + &slab_obj_ext_has_codetag_key);
> +}
> +#else
> +static inline bool slab_obj_ext_has_codetag(void)
> +{
> + return false;
> +}
> +#endif
> +
> static inline size_t static_obj_ext_size(void)
> {
> size_t sz = 0;
> diff --git a/mm/slub.c b/mm/slub.c
> index dd15af8abd62..4200e7105b30 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -213,6 +213,11 @@ DEFINE_STATIC_KEY_FALSE(slub_debug_enabled);
> static DEFINE_STATIC_KEY_FALSE(strict_numa);
> #endif
>
> +#ifdef CONFIG_MEM_ALLOC_PROFILING
> +DEFINE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
> + slab_obj_ext_has_codetag_key);
> +#endif
> +
> /* Structure holding extra parameters for slab allocations */
> struct slab_alloc_context {
> unsigned long caller_addr;
> @@ -2415,6 +2420,26 @@ alloc_tagging_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
> __alloc_tagging_slab_free_hook(s, slab, p, objects);
> }
>
> +/*
> + * Make sure the static key used by slab_obj_ext_has_codetag() reflects the
> + * value of !mem_alloc_profiling_permanently_disabled()
> + *
> + * Any later mem alloc profiling shutdown won't be reflected in the static key
> + * because obj_exts with codetags might already exist.
> + */
> +static void __init slab_obj_ext_has_codetag_init(void)
> +{
> + bool key_enabled = IS_ENABLED(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT);

nit: This seems a bit indirect. Reader needs to remember that
slab_obj_ext_has_codetag_key is initialized based on
CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT. Wouldn't below code be
simpler?:

bool need_codetag = !mem_alloc_profiling_permanently_disabled();
if (need_codetag != static_key_enabled(&slab_obj_ext_has_codetag_key)) {
if (need_codetag)
static_branch_enable(&slab_obj_ext_has_codetag_key);
else
static_branch_disable(&slab_obj_ext_has_codetag_key);
}

It might be less performant but who cares, it's __init function used
only one time.

> + bool need_codetag = !mem_alloc_profiling_permanently_disabled();
> +
> + if (key_enabled != need_codetag) {
> + if (need_codetag)
> + static_branch_enable(&slab_obj_ext_has_codetag_key);
> + else
> + static_branch_disable(&slab_obj_ext_has_codetag_key);
> + }
> +}
> +
> #else /* CONFIG_MEM_ALLOC_PROFILING */
>
> static inline void
> @@ -2429,6 +2454,10 @@ alloc_tagging_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
> {
> }
>
> +static inline void slab_obj_ext_has_codetag_init(void)
> +{
> +}
> +
> #endif /* CONFIG_MEM_ALLOC_PROFILING */
>
>
> @@ -8541,6 +8570,8 @@ void __init kmem_cache_init(void)
> boot_kmem_cache_node;
> int node;
>
> + slab_obj_ext_has_codetag_init();
> +
> if (debug_guardpage_minorder())
> slub_max_order = 0;
>
>
> --
> 2.55.0
>