Re: [PATCH slab v5 5/6] slab: Reuse first bit for OBJEXTS_ALLOC_FAIL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



+Suren, Roman

On Mon, Sep 08, 2025 at 06:00:06PM -0700, Alexei Starovoitov wrote:
> From: Alexei Starovoitov <ast@xxxxxxxxxx>
> 
> Since the combination of valid upper bits in slab->obj_exts with
> OBJEXTS_ALLOC_FAIL bit can never happen,
> use OBJEXTS_ALLOC_FAIL == (1ull << 0) as a magic sentinel
> instead of (1ull << 2) to free up bit 2.
> 
> Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx>

Are we low on bits that we need to do this or is this good to have
optimization but not required?

I do have some questions on the state of slab->obj_exts even before this
patch for Suren, Roman, Vlastimil and others:

Suppose we newly allocate struct slab for a SLAB_ACCOUNT cache and tried
to allocate obj_exts for it which failed. The kernel will set
OBJEXTS_ALLOC_FAIL in slab->obj_exts (Note that this can only be set for
new slab allocation and only for SLAB_ACCOUNT caches i.e. vec allocation
failure for memory profiling does not set this flag).

Now in the post alloc hook, either through memory profiling or through
memcg charging, we will try again to allocate the vec and before that we
will call slab_obj_exts() on the slab which has:

	unsigned long obj_exts = READ_ONCE(slab->obj_exts);

	VM_BUG_ON_PAGE(obj_exts && !(obj_exts & MEMCG_DATA_OBJEXTS), slab_page(slab));

It seems like the above VM_BUG_ON_PAGE() will trigger because obj_exts
will have OBJEXTS_ALLOC_FAIL but it should not, right? Or am I missing
something? After the following patch we will aliasing be MEMCG_DATA_OBJEXTS
and OBJEXTS_ALLOC_FAIL and will avoid this trigger though which also
seems unintended.

Next question: OBJEXTS_ALLOC_FAIL is for memory profiling and we never
set it when memcg is disabled and memory profiling is enabled or even
with both memcg and memory profiling are enabled but cache does not have
SLAB_ACCOUNT. This seems unintentional as well, right?

Also I think slab_obj_exts() needs to handle OBJEXTS_ALLOC_FAIL explicitly.


> ---
>  include/linux/memcontrol.h | 10 ++++++++--
>  mm/slub.c                  |  2 +-
>  2 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index 785173aa0739..d254c0b96d0d 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -341,17 +341,23 @@ enum page_memcg_data_flags {
>  	__NR_MEMCG_DATA_FLAGS  = (1UL << 2),
>  };
>  
> +#define __OBJEXTS_ALLOC_FAIL	MEMCG_DATA_OBJEXTS
>  #define __FIRST_OBJEXT_FLAG	__NR_MEMCG_DATA_FLAGS
>  
>  #else /* CONFIG_MEMCG */
>  
> +#define __OBJEXTS_ALLOC_FAIL	(1UL << 0)
>  #define __FIRST_OBJEXT_FLAG	(1UL << 0)
>  
>  #endif /* CONFIG_MEMCG */
>  
>  enum objext_flags {
> -	/* slabobj_ext vector failed to allocate */
> -	OBJEXTS_ALLOC_FAIL = __FIRST_OBJEXT_FLAG,
> +	/*
> +	 * Use bit 0 with zero other bits to signal that slabobj_ext vector
> +	 * failed to allocate. The same bit 0 with valid upper bits means
> +	 * MEMCG_DATA_OBJEXTS.
> +	 */
> +	OBJEXTS_ALLOC_FAIL = __OBJEXTS_ALLOC_FAIL,
>  	/* 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 212161dc0f29..61841ba72120 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2051,7 +2051,7 @@ static inline void handle_failed_objexts_alloc(unsigned long obj_exts,
>  	 * objects with no tag reference. Mark all references in this
>  	 * vector as empty to avoid warnings later on.
>  	 */
> -	if (obj_exts & OBJEXTS_ALLOC_FAIL) {
> +	if (obj_exts == OBJEXTS_ALLOC_FAIL) {
>  		unsigned int i;
>  
>  		for (i = 0; i < objects; i++)
> -- 
> 2.47.3
> 




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux