Re: [PATCH RFC 11/12] mm/slab: add slab_needs_objcg() helper
Suren Baghdasaryan <[email protected]>
| Newsgroups | org.kernel.vger.cgroups,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAJuCfpEwBeuo-70-GZJ1jMZP6+vopmuEsBScvHki97ccRyDDuA@mail.gmail.com> |
On Wed, Jul 15, 2026 at 3:11 AM Vlastimil Babka (SUSE) <[email protected]> wrote: > > Slabs of some caches never need the objcg part of struct slabobj_ext. > Introduce a helper to query this for a slab. > > Currently only is_kmalloc_normal() caches are considered as not needing > objcg's. We could also consider all kmem caches without SLAB_ACCOUNT, > however some might be used with and without __GFP_ACCOUNT concurrently > and we currently don't restrict that. This can be improved later. > > To make the evaluation of slab_needs_objcg() faster in the allocation > and free fast paths, add a obj_exts_needs_objcg flag into slab itself. > This optimization is only available on 64bit architectures where free > bits are available for the flag. > > Signed-off-by: Vlastimil Babka (SUSE) <[email protected]> Reviewed-by: Suren Baghdasaryan <[email protected]> > --- > mm/kfence/core.c | 3 +++ > mm/slab.h | 31 +++++++++++++++++++++++++++++-- > mm/slub.c | 4 ++++ > 3 files changed, 36 insertions(+), 2 deletions(-) > > diff --git a/mm/kfence/core.c b/mm/kfence/core.c > index 717e8baf7e5d..afeaf80484ad 100644 > --- a/mm/kfence/core.c > +++ b/mm/kfence/core.c > @@ -640,6 +640,9 @@ static unsigned long kfence_init_pool(void) > struct slab *slab = page_slab(page); > slab->obj_exts = (unsigned long)&kfence_metadata_init[i / 2 - 1].obj_exts | > MEMCG_DATA_OBJEXTS; > +#ifdef CONFIG_64BIT > + slab->obj_exts_needs_objcg = 1; > +#endif > #endif > } > > diff --git a/mm/slab.h b/mm/slab.h > index a50347c9dbe3..948d075cdbef 100644 > --- a/mm/slab.h > +++ b/mm/slab.h > @@ -81,10 +81,11 @@ struct freelist_counters { > #ifdef CONFIG_64BIT > /* > * Some optimizations use free bits in 'counters' field > - * to save memory. If these free bits are not available, > - * such optimizations are disabled. > + * to save memory or CPU. If these free bits are not > + * available, such optimizations are disabled. > */ > unsigned obj_exts_in_object:1; > + unsigned obj_exts_needs_objcg:1; > #endif > }; > }; > @@ -580,6 +581,32 @@ static inline bool slab_obj_ext_has_codetag(void) > } > #endif > > +#ifdef CONFIG_MEMCG > +static inline bool cache_needs_objcg(struct kmem_cache *cache) > +{ > + return !is_kmalloc_normal(cache); > +} > + > +static inline bool slab_needs_objcg(struct slab *slab) > +{ > +#ifdef CONFIG_64BIT > + return slab->obj_exts_needs_objcg; > +#else > + return cache_needs_objcg(slab->slab_cache); > +#endif > +} > +#else > +static inline bool cache_needs_objcg(struct kmem_cache *cache) > +{ > + return false; > +} > + > +static inline bool slab_needs_objcg(struct slab *slab) > +{ > + 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 4200e7105b30..771d73abacb6 100644 > --- a/mm/slub.c > +++ b/mm/slub.c > @@ -3426,6 +3426,10 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, > > slab->objects = oo_objects(oo); > > +#ifdef CONFIG_64BIT > + if (cache_needs_objcg(s)) > + slab->obj_exts_needs_objcg = 1; > +#endif > slab->slab_cache = s; > > kasan_poison_slab(slab); > > -- > 2.55.0 >