Re: [PATCH RFC 12/12] mm/slab: stop allocating objcg pointers when unnecessary

Suren Baghdasaryan <[email protected]>
Newsgroups org.kernel.vger.cgroups,org.kernel.vger.linux-kernel
Message-ID <CAJuCfpHuXu3BDf93zeBQWSW_k5wApegp44rHoZwk5Ym6xxbqEA@mail.gmail.com>
On Wed, Jul 15, 2026 at 3:11 AM Vlastimil Babka (SUSE)
<[email protected]> wrote:
>
> Start using the slab_needs_objcg() helper to calculate slabobj_ext size.
> Caches that we know to never need objcg pointers (currently
> KMALLOC_NORMAL caches) will thus stop wasting memory on them when memory
> allocation profiling is enabled.
>
> For things to work properly, we need to also add slab_needs_objcg()
> checks to mem_cgroup_from_obj_slab() and memcg_slab_free_hook(), because
> when obj_exts array exists for a slab only due to mem_alloc profiling,
> we would otherwise attempt to access a non-existing objcg pointer in
> that slab.
>
> The function __memcg_slab_post_alloc_hook() should not be possible to
> call for a slab where slab_needs_objcg() is false, but add a DEBUG_VM
> check there to prevent breaking this assumption accidentally.
>
> Signed-off-by: Vlastimil Babka (SUSE) <[email protected]>

The change looks nice and simple. I'll take some more time to check if
we missed anything.
Only one nit below.

> ---
>  mm/memcontrol.c |  6 ++++++
>  mm/slab.h       | 12 ++++++++++--
>  mm/slub.c       |  3 +++
>  3 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 6303a2b1a9d0..09659722ec85 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -2871,6 +2871,9 @@ struct mem_cgroup *mem_cgroup_from_obj_slab(struct slab *slab, void *p)
>         if (!obj_exts)
>                 return NULL;
>
> +       if (!slab_needs_objcg(slab))
> +               return NULL;
> +
>         get_slab_obj_exts(obj_exts);
>         obj_ext = slab_obj_ext(slab->slab_cache, slab, obj_exts, p);
>         objcg = *slab_obj_ext_objcgp(obj_ext);
> @@ -3581,6 +3584,9 @@ bool __memcg_slab_post_alloc_hook(struct kmem_cache *s, struct list_lru *lru,
>
>                 slab = virt_to_slab(p[i]);
>
> +               if (IS_ENABLED(CONFIG_DEBUG_VM) && WARN_ON_ONCE(!slab_needs_objcg(slab)))
> +                       continue;
> +
>                 if (!slab_obj_exts(slab) &&
>                     alloc_slab_obj_exts(slab, s, flags, slab_alloc_flags)) {
>                         continue;
> diff --git a/mm/slab.h b/mm/slab.h
> index 948d075cdbef..072cc2506756 100644
> --- a/mm/slab.h
> +++ b/mm/slab.h
> @@ -622,7 +622,15 @@ static inline size_t static_obj_ext_size(void)
>
>  static inline size_t slab_obj_ext_size(struct slab *slab)
>  {
> -       return static_obj_ext_size();

Maybe now we should rename static_obj_ext_size() to
static_obj_ext_max_size() as it reflects the max possible size of
slabobj_ext?

> +       size_t sz = 0;
> +
> +       if (slab_needs_objcg(slab))
> +               sz += 1;
> +
> +       if (slab_obj_ext_has_codetag())
> +               sz += 1;
> +
> +       return sizeof(struct slabobj_ext) * sz;
>  }
>
>  #ifdef CONFIG_SLAB_OBJ_EXT
> @@ -741,7 +749,7 @@ static inline struct obj_cgroup **slab_obj_ext_objcgp(struct slabobj_ext *obj_ex
>  static inline union codetag_ref *
>  slab_obj_ext_codetag_ref(struct slab *slab, struct slabobj_ext *obj_ext)
>  {
> -       if (IS_ENABLED(CONFIG_MEMCG))
> +       if (slab_needs_objcg(slab))
>                 obj_ext += 1;
>
>         return &obj_ext->_ctref;
> diff --git a/mm/slub.c b/mm/slub.c
> index 771d73abacb6..09c4931e5435 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2503,6 +2503,9 @@ void memcg_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
>         if (likely(!obj_exts))
>                 return;
>
> +       if (!slab_needs_objcg(slab))
> +               return;
> +
>         get_slab_obj_exts(obj_exts);
>         __memcg_slab_free_hook(s, slab, p, objects, obj_exts);
>         put_slab_obj_exts(obj_exts);
>
> --
> 2.55.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.