All of lore.kernel.org
 help / color / mirror / Atom feed
From: Harry Yoo <harry.yoo@oracle.com>
To: Hao Li <hao.li@linux.dev>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Vlastimil Babka <vbabka@suse.cz>,
	Christoph Lameter <cl@gentwo.org>,
	David Rientjes <rientjes@google.com>,
	Roman Gushchin <roman.gushchin@linux.dev>,
	Alexei Starovoitov <ast@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Uladzislau Rezki <urezki@gmail.com>,
	Suren Baghdasaryan <surenb@google.com>,
	linux-mm@kvack.org
Subject: Re: [PATCH V2 2/2] mm/slab: drop the OBJEXTS_NOSPIN_ALLOC flag from enum objext_flags
Date: Tue, 10 Feb 2026 19:32:45 +0900	[thread overview]
Message-ID: <aYsJTWFQrDcCVsuX@hyeyoo> (raw)
In-Reply-To: <ym376ht2w32x3zmfpteiezo6goelaiokvk6ujgp4imdwpw6o2s@tz2f5hvm3ezs>

On Tue, Feb 10, 2026 at 04:57:42PM +0800, Hao Li wrote:
> On Tue, Feb 10, 2026 at 01:46:42PM +0900, Harry Yoo wrote:
> > OBJEXTS_NOSPIN_ALLOC was used to remember whether a slabobj_ext vector
> > was allocated via kmalloc_nolock(), so that free_slab_obj_exts() could
> > call kfree_nolock() instead of kfree().
> > 
> > Now that kfree() supports freeing kmalloc_nolock() objects, this flag is
> > no longer needed. Instead, pass the allow_spin parameter down to
> > free_slab_obj_exts() to determine whether kfree_nolock() or kfree()
> > should be called in the free path, and free one bit in
> > enum objext_flags.
> > 
> > Acked-by: Alexei Starovoitov <ast@kernel.org>
> > Signed-off-by: Harry Yoo <harry.yoo@oracle.com>
> > ---
> >  include/linux/memcontrol.h |  3 +--
> >  mm/slub.c                  | 18 ++++++++----------
> >  2 files changed, 9 insertions(+), 12 deletions(-)
> > 
> > diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> > index 0651865a4564..bb789ec4a2a2 100644
> > --- a/include/linux/memcontrol.h
> > +++ b/include/linux/memcontrol.h
> > @@ -359,8 +359,7 @@ enum objext_flags {
> >  	 * MEMCG_DATA_OBJEXTS.
> >  	 */
> >  	OBJEXTS_ALLOC_FAIL = __OBJEXTS_ALLOC_FAIL,
> > -	/* slabobj_ext vector allocated with kmalloc_nolock() */
> > -	OBJEXTS_NOSPIN_ALLOC = __FIRST_OBJEXT_FLAG,
> > +	__OBJEXTS_FLAG_UNUSED = __FIRST_OBJEXT_FLAG,
> >  	/* the next bit after the last actual flag */
> >  	__NR_OBJEXTS_FLAGS  = (__FIRST_OBJEXT_FLAG << 1),
> >  };
> > diff --git a/mm/slub.c b/mm/slub.c
> > index 63b03fd62ca7..a73a80b33ff9 100644
> > --- a/mm/slub.c
> > +++ b/mm/slub.c
> > @@ -2189,8 +2189,6 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
> >  			virt_to_slab(vec)->slab_cache == s);
> >  
> >  	new_exts = (unsigned long)vec;
> > -	if (unlikely(!allow_spin))
> > -		new_exts |= OBJEXTS_NOSPIN_ALLOC;
> >  #ifdef CONFIG_MEMCG
> >  	new_exts |= MEMCG_DATA_OBJEXTS;
> >  #endif
> > @@ -2228,7 +2226,7 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
> >  	return 0;
> >  }
> >  
> > -static inline void free_slab_obj_exts(struct slab *slab)
> > +static inline void free_slab_obj_exts(struct slab *slab, bool allow_spin)
> >  {
> >  	struct slabobj_ext *obj_exts;
> >  
> > @@ -2256,10 +2254,10 @@ static inline void free_slab_obj_exts(struct slab *slab)
> >  	 * the extension for obj_exts is expected to be NULL.
> >  	 */
> >  	mark_objexts_empty(obj_exts);
> > -	if (unlikely(READ_ONCE(slab->obj_exts) & OBJEXTS_NOSPIN_ALLOC))
> > -		kfree_nolock(obj_exts);
> > -	else
> > +	if (allow_spin)
> >  		kfree(obj_exts);
> > +	else
> > +		kfree_nolock(obj_exts);
> 
> Looks good to me.
> 
> One small observation from my side: at first glance I briefly wondered if we
> could ever allocate in an allow_spin=true context but free in an
> allow_spin=false context, potentially resulting in a kmalloc() -> kfree_nolock()
> mismatch.

Right, kmalloc() -> kfree_nolock() is not supported and must be avoided.

> After taking a closer look, the only case where "free_new_slab_nolock() -> ...
> -> free_slab_obj_exts()" runs with allow_spin=false is along the "___slab_alloc
> -> alloc_single_from_new_slab()/alloc_from_new_slab()" path.

Right, this is when trylock failed after allocating new slab.

> In that scenario, alloc_slab_obj_exts() is also called under allow_spin=false
> and uses kmalloc_nolock(), so the allocation/free paths remain consistent.
> So "kmalloc() -> kfree_nolock()" case can't happen,
> and the code looks solid to me!

Nice analysis, thanks!

Yeah, for this reason, we should not free slabs that are allocated
with allow_spin == true, when allow_spin is false.

kfree_nolock() avoids this by deferring frees in the slowpath.
If someone is tempated to rework kfree_nolock() slowpath, he or she
should be careful :)

> Reviewed-by: Hao Li <hao.li@linux.dev>

Thanks for review, Hao!

-- 
Cheers,
Harry / Hyeonggon


  reply	other threads:[~2026-02-10 10:33 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-10  4:46 [PATCH V2 0/2] mm/slab: support kmalloc_nolock() -> kfree[_rcu]() Harry Yoo
2026-02-10  4:46 ` [PATCH V2 1/2] mm/slab: allow freeing kmalloc_nolock()'d objects using kfree[_rcu]() Harry Yoo
2026-02-10  4:46 ` [PATCH V2 2/2] mm/slab: drop the OBJEXTS_NOSPIN_ALLOC flag from enum objext_flags Harry Yoo
2026-02-10  8:57   ` Hao Li
2026-02-10 10:32     ` Harry Yoo [this message]
2026-02-10 14:08 ` [PATCH V2 0/2] mm/slab: support kmalloc_nolock() -> kfree[_rcu]() Vlastimil Babka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aYsJTWFQrDcCVsuX@hyeyoo \
    --to=harry.yoo@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=ast@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=cl@gentwo.org \
    --cc=hao.li@linux.dev \
    --cc=linux-mm@kvack.org \
    --cc=rientjes@google.com \
    --cc=roman.gushchin@linux.dev \
    --cc=surenb@google.com \
    --cc=urezki@gmail.com \
    --cc=vbabka@suse.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.