linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object
@ 2025-07-23  8:03 Zhenhua Huang
  2025-07-23  9:19 ` Harry Yoo
  2025-07-23 11:31 ` Kent Overstreet
  0 siblings, 2 replies; 7+ messages in thread
From: Zhenhua Huang @ 2025-07-23  8:03 UTC (permalink / raw)
  To: kent.overstreet, rientjes, vbabka, cl, roman.gushchin, harry.yoo,
	surenb, pasha.tatashin, akpm, corbet
  Cc: linux-mm, linux-doc, linux-kernel, quic_tingweiz, Zhenhua Huang

Mem profiling feature tracks both "alloc_slab_page"(page level) and slub
object level allocations. To track object level allocations,
slabobj_ext consumes 16 bytes per object for profiling slub object if
CONFIG_MEMCG is set.
Based on the data I've collected, this overhead accounts for approximately
5.7% of slub memory usage — a considerable cost.
w/ noslub  slub_debug=-
Slab:              87520 kB
w/o noslub slub_debug=-
Slab:              92812 kB

While In some scenarios, we may choose not to delve into SLUB allocation
details if initial triage indicates that SLUB memory usage is within
acceptable limits. To support this, a control knob is introduced to enable
or disable SLUB object tracking.
The "noslub" knob disables SLUB tracking, preventing further allocation of
slabobj_ext structures.

Signed-off-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
---
 Documentation/mm/allocation-profiling.rst |  7 +++++-
 include/linux/alloc_tag.h                 |  8 +++++++
 lib/alloc_tag.c                           | 26 +++++++++++++++++------
 mm/slub.c                                 | 10 ++++-----
 4 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/Documentation/mm/allocation-profiling.rst b/Documentation/mm/allocation-profiling.rst
index 316311240e6a..9ecae74e0365 100644
--- a/Documentation/mm/allocation-profiling.rst
+++ b/Documentation/mm/allocation-profiling.rst
@@ -18,7 +18,7 @@ kconfig options:
   missing annotation
 
 Boot parameter:
-  sysctl.vm.mem_profiling={0|1|never}[,compressed]
+  sysctl.vm.mem_profiling={0|1|never}[,compressed][,noslub]
 
   When set to "never", memory allocation profiling overhead is minimized and it
   cannot be enabled at runtime (sysctl becomes read-only).
@@ -30,6 +30,11 @@ Boot parameter:
   If compression fails, a warning is issued and memory allocation profiling gets
   disabled.
 
+  The optional noslub parameter disables tracking of individual SLUB objects. This
+  approach, similar to how page owner tracking works, relies on slub_debug for SLUB
+  object insights instead. While this reduces memory overhead, it also limits the
+  ability to observe detailed SLUB allocation behavior.
+
 sysctl:
   /proc/sys/vm/mem_profiling
 
diff --git a/include/linux/alloc_tag.h b/include/linux/alloc_tag.h
index 8f7931eb7d16..af3c139712ce 100644
--- a/include/linux/alloc_tag.h
+++ b/include/linux/alloc_tag.h
@@ -134,6 +134,13 @@ static inline bool mem_alloc_profiling_enabled(void)
 				   &mem_alloc_profiling_key);
 }
 
+DECLARE_STATIC_KEY_TRUE(slub_mem_alloc_profiling_key);
+
+static inline bool slub_mem_alloc_profiling_enabled(void)
+{
+	return static_key_enabled(&slub_mem_alloc_profiling_key);
+}
+
 static inline struct alloc_tag_counters alloc_tag_read(struct alloc_tag *tag)
 {
 	struct alloc_tag_counters v = { 0, 0 };
@@ -227,6 +234,7 @@ static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes)
 
 #define DEFINE_ALLOC_TAG(_alloc_tag)
 static inline bool mem_alloc_profiling_enabled(void) { return false; }
+static inline bool slub_mem_alloc_profiling_enabled(void) { return false; }
 static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag,
 				 size_t bytes) {}
 static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes) {}
diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
index 0142bc916f73..b79b0d987427 100644
--- a/lib/alloc_tag.c
+++ b/lib/alloc_tag.c
@@ -33,6 +33,8 @@ DEFINE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
 EXPORT_SYMBOL(mem_alloc_profiling_key);
 
 DEFINE_STATIC_KEY_FALSE(mem_profiling_compressed);
+DEFINE_STATIC_KEY_TRUE(slub_mem_alloc_profiling_key);
+EXPORT_SYMBOL(slub_mem_alloc_profiling_key);
 
 struct alloc_tag_kernel_section kernel_tags = { NULL, 0 };
 unsigned long alloc_tag_ref_mask;
@@ -710,6 +712,7 @@ static inline void free_mod_tags_mem(void) {}
 static int __init setup_early_mem_profiling(char *str)
 {
 	bool compressed = false;
+	bool noslub = false;
 	bool enable;
 
 	if (!str || !str[0])
@@ -725,16 +728,19 @@ static int __init setup_early_mem_profiling(char *str)
 		if (kstrtobool(token, &enable))
 			return -EINVAL;
 
-		if (str) {
-
-			if (strcmp(str, "compressed"))
+		while ((token = strsep(&str, ",")) != NULL) {
+			if (strcmp(token, "compressed") == 0)
+				compressed = true;
+			else if (strcmp(token, "noslub") == 0)
+				noslub = true;
+			else
 				return -EINVAL;
-
-			compressed = true;
 		}
 		mem_profiling_support = true;
-		pr_info("Memory allocation profiling is enabled %s compression and is turned %s!\n",
-			compressed ? "with" : "without", enable ? "on" : "off");
+		pr_info("Memory allocation profiling is enabled %s compression, %s slub track and is turned %s!\n",
+			compressed ? "with" : "without",
+			noslub ? "without" : "with",
+			enable ? "on" : "off");
 	}
 
 	if (enable != mem_alloc_profiling_enabled()) {
@@ -749,6 +755,12 @@ static int __init setup_early_mem_profiling(char *str)
 		else
 			static_branch_disable(&mem_profiling_compressed);
 	}
+	if (noslub == static_key_enabled(&slub_mem_alloc_profiling_key)) {
+		if (noslub)
+			static_branch_disable(&slub_mem_alloc_profiling_key);
+		else
+			static_branch_enable(&slub_mem_alloc_profiling_key);
+	}
 
 	return 0;
 }
diff --git a/mm/slub.c b/mm/slub.c
index 31e11ef256f9..e8378b092b30 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2093,7 +2093,7 @@ prepare_slab_obj_exts_hook(struct kmem_cache *s, gfp_t flags, void *p)
 	return slab_obj_exts(slab) + obj_to_index(s, slab, p);
 }
 
-/* Should be called only if mem_alloc_profiling_enabled() */
+/* Should be called only if slub_mem_alloc_profiling_enabled() */
 static noinline void
 __alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
 {
@@ -2102,7 +2102,7 @@ __alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
 	obj_exts = prepare_slab_obj_exts_hook(s, flags, object);
 	/*
 	 * Currently obj_exts is used only for allocation profiling.
-	 * If other users appear then mem_alloc_profiling_enabled()
+	 * If other users appear then slub_mem_alloc_profiling_enabled()
 	 * check should be added before alloc_tag_add().
 	 */
 	if (likely(obj_exts))
@@ -2112,11 +2112,11 @@ __alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
 static inline void
 alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
 {
-	if (mem_alloc_profiling_enabled())
+	if (slub_mem_alloc_profiling_enabled())
 		__alloc_tagging_slab_alloc_hook(s, object, flags);
 }
 
-/* Should be called only if mem_alloc_profiling_enabled() */
+/* Should be called only if slub_mem_alloc_profiling_enabled() */
 static noinline void
 __alloc_tagging_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
 			       int objects)
@@ -2143,7 +2143,7 @@ static inline void
 alloc_tagging_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
 			     int objects)
 {
-	if (mem_alloc_profiling_enabled())
+	if (slub_mem_alloc_profiling_enabled())
 		__alloc_tagging_slab_free_hook(s, slab, p, objects);
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object
  2025-07-23  8:03 [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object Zhenhua Huang
@ 2025-07-23  9:19 ` Harry Yoo
  2025-07-23 10:21   ` Zhenhua Huang
  2025-07-23 11:38   ` Kent Overstreet
  2025-07-23 11:31 ` Kent Overstreet
  1 sibling, 2 replies; 7+ messages in thread
From: Harry Yoo @ 2025-07-23  9:19 UTC (permalink / raw)
  To: Zhenhua Huang
  Cc: kent.overstreet, rientjes, vbabka, cl, roman.gushchin, surenb,
	pasha.tatashin, akpm, corbet, linux-mm, linux-doc, linux-kernel,
	quic_tingweiz

The subject is a bit misleading. I think it should be something like
"alloc_tag: add an option to disable slab object accounting".

On Wed, Jul 23, 2025 at 04:03:28PM +0800, Zhenhua Huang wrote:
> Mem profiling feature tracks both "alloc_slab_page"(page level) and slub
> object level allocations. To track object level allocations,
> slabobj_ext consumes 16 bytes per object for profiling slub object if
> CONFIG_MEMCG is set.
> Based on the data I've collected, this overhead accounts for approximately
> 5.7% of slub memory usage — a considerable cost.
> w/ noslub  slub_debug=-
> Slab:              87520 kB
> w/o noslub slub_debug=-
> Slab:              92812 kB

Yes, the cost is not small and I hate that we have to pay 16 bytes of
memory overhead for each slab object when both memcg and memory profiling
are enabled.

> While In some scenarios, we may choose not to delve into SLUB allocation
> details if initial triage indicates that SLUB memory usage is within
> acceptable limits. To support this, a control knob is introduced to enable
> or disable SLUB object tracking.

But what if slab memory usage is not within acceptable limit,
reboot without noslub and profile it again?

You should expect to sacrifice some performance and memory by enabling
memory allocation profiling. I'm not sure if it's worth optimizing it
at the cost of disabling slab accounting entirely.

Anyway, that's my opinion - the memory allocation profiling
maintainers might say something different.

> The "noslub" knob disables SLUB tracking, preventing further allocation of
> slabobj_ext structures.

nit: "noslub" is not a good name because slub is an implementation
of slab allocator. For the same reason "slub_debug" is deprecated and
"slab_debug" is recommended instead. Maybe "noslab"?

> Signed-off-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
> ---
>  Documentation/mm/allocation-profiling.rst |  7 +++++-
>  include/linux/alloc_tag.h                 |  8 +++++++
>  lib/alloc_tag.c                           | 26 +++++++++++++++++------
>  mm/slub.c                                 | 10 ++++-----
>  4 files changed, 38 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/mm/allocation-profiling.rst b/Documentation/mm/allocation-profiling.rst
> index 316311240e6a..9ecae74e0365 100644
> --- a/Documentation/mm/allocation-profiling.rst
> +++ b/Documentation/mm/allocation-profiling.rst
> @@ -18,7 +18,7 @@ kconfig options:
>    missing annotation
>  
>  Boot parameter:
> -  sysctl.vm.mem_profiling={0|1|never}[,compressed]
> +  sysctl.vm.mem_profiling={0|1|never}[,compressed][,noslub]
>  
>    When set to "never", memory allocation profiling overhead is minimized and it
>    cannot be enabled at runtime (sysctl becomes read-only).
> @@ -30,6 +30,11 @@ Boot parameter:
>    If compression fails, a warning is issued and memory allocation profiling gets
>    disabled.
>  
> +  The optional noslub parameter disables tracking of individual SLUB objects. This
> +  approach, similar to how page owner tracking works, relies on slub_debug for SLUB
> +  object insights instead. While this reduces memory overhead, it also limits the
> +  ability to observe detailed SLUB allocation behavior.

I think you don't really want to use slab_debug to account slab memory
if you care about performance & memory overhead.

>  sysctl:
>    /proc/sys/vm/mem_profiling
>  

-- 
Cheers,
Harry / Hyeonggon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object
  2025-07-23  9:19 ` Harry Yoo
@ 2025-07-23 10:21   ` Zhenhua Huang
  2025-07-23 11:38   ` Kent Overstreet
  1 sibling, 0 replies; 7+ messages in thread
From: Zhenhua Huang @ 2025-07-23 10:21 UTC (permalink / raw)
  To: Harry Yoo
  Cc: kent.overstreet, rientjes, vbabka, cl, roman.gushchin, surenb,
	pasha.tatashin, akpm, corbet, linux-mm, linux-doc, linux-kernel,
	quic_tingweiz

Thanks Harry for your quick comments.

On 2025/7/23 17:19, Harry Yoo wrote:
> The subject is a bit misleading. I think it should be something like
> "alloc_tag: add an option to disable slab object accounting".

Oh, Yeah, it's an alloc_tag change. Thanks and will update.

> 
> On Wed, Jul 23, 2025 at 04:03:28PM +0800, Zhenhua Huang wrote:
>> Mem profiling feature tracks both "alloc_slab_page"(page level) and slub
>> object level allocations. To track object level allocations,
>> slabobj_ext consumes 16 bytes per object for profiling slub object if
>> CONFIG_MEMCG is set.
>> Based on the data I've collected, this overhead accounts for approximately
>> 5.7% of slub memory usage — a considerable cost.
>> w/ noslub  slub_debug=-
>> Slab:              87520 kB
>> w/o noslub slub_debug=-
>> Slab:              92812 kB
> 
> Yes, the cost is not small and I hate that we have to pay 16 bytes of
> memory overhead for each slab object when both memcg and memory profiling
> are enabled.
> 
>> While In some scenarios, we may choose not to delve into SLUB allocation
>> details if initial triage indicates that SLUB memory usage is within
>> acceptable limits. To support this, a control knob is introduced to enable
>> or disable SLUB object tracking.
> 
> But what if slab memory usage is not within acceptable limit,
> reboot without noslub and profile it again?

Yes. The idea is similar with: when we are willing to see slab 
allocation stacks we add "slab_debug=U". Basically if we enable page 
owner only, we can't see slab allocation stacks as well.

> 
> You should expect to sacrifice some performance and memory by enabling
> memory allocation profiling. I'm not sure if it's worth optimizing it
> at the cost of disabling slab accounting entirely.

Actually, we can still track the total slab usage through 
alloc_slab_page; in my opinion, what's being disabled here is the 
accounting at the slab object level.

> 
> Anyway, that's my opinion - the memory allocation profiling
> maintainers might say something different.

This, as I understand it, is the core concern addressed by the patch. 
The background is that some OEMs have raised concerns about the memory 
overhead introduced by this debug feature when used in production 
builds. While page-level tracking can now be compressed into page flags, 
I haven't seen a similar solution for slab object-level tracking yet.
In a real Android platform, we see 24MB memory are cost from 
alloc_slab_obj_exts :)

> 
>> The "noslub" knob disables SLUB tracking, preventing further allocation of
>> slabobj_ext structures.
> 
> nit: "noslub" is not a good name because slub is an implementation
> of slab allocator. For the same reason "slub_debug" is deprecated and
> "slab_debug" is recommended instead. Maybe "noslab"?

Thanks for pointing out, will update.

> 
>> Signed-off-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
>> ---
>>   Documentation/mm/allocation-profiling.rst |  7 +++++-
>>   include/linux/alloc_tag.h                 |  8 +++++++
>>   lib/alloc_tag.c                           | 26 +++++++++++++++++------
>>   mm/slub.c                                 | 10 ++++-----
>>   4 files changed, 38 insertions(+), 13 deletions(-)
>>
>> diff --git a/Documentation/mm/allocation-profiling.rst b/Documentation/mm/allocation-profiling.rst
>> index 316311240e6a..9ecae74e0365 100644
>> --- a/Documentation/mm/allocation-profiling.rst
>> +++ b/Documentation/mm/allocation-profiling.rst
>> @@ -18,7 +18,7 @@ kconfig options:
>>     missing annotation
>>   
>>   Boot parameter:
>> -  sysctl.vm.mem_profiling={0|1|never}[,compressed]
>> +  sysctl.vm.mem_profiling={0|1|never}[,compressed][,noslub]
>>   
>>     When set to "never", memory allocation profiling overhead is minimized and it
>>     cannot be enabled at runtime (sysctl becomes read-only).
>> @@ -30,6 +30,11 @@ Boot parameter:
>>     If compression fails, a warning is issued and memory allocation profiling gets
>>     disabled.
>>   
>> +  The optional noslub parameter disables tracking of individual SLUB objects. This
>> +  approach, similar to how page owner tracking works, relies on slub_debug for SLUB
>> +  object insights instead. While this reduces memory overhead, it also limits the
>> +  ability to observe detailed SLUB allocation behavior.
> 
> I think you don't really want to use slab_debug to account slab memory
> if you care about performance & memory overhead.

I should update my wording:) What I meant is that this case is similar 
to how we handle page owner versus slab_debug: typically, we enable page 
owner firstly, and only turn on slab_debug when we need detailed slab 
object tracking. Both are optional and left to the end user to decide 
whether to enable them.

> 
>>   sysctl:
>>     /proc/sys/vm/mem_profiling
>>   
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object
  2025-07-23  8:03 [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object Zhenhua Huang
  2025-07-23  9:19 ` Harry Yoo
@ 2025-07-23 11:31 ` Kent Overstreet
  2025-07-24  3:57   ` Zhenhua Huang
  1 sibling, 1 reply; 7+ messages in thread
From: Kent Overstreet @ 2025-07-23 11:31 UTC (permalink / raw)
  To: Zhenhua Huang
  Cc: rientjes, vbabka, cl, roman.gushchin, harry.yoo, surenb,
	pasha.tatashin, akpm, corbet, linux-mm, linux-doc, linux-kernel,
	quic_tingweiz

On Wed, Jul 23, 2025 at 04:03:28PM +0800, Zhenhua Huang wrote:
> Mem profiling feature tracks both "alloc_slab_page"(page level) and slub
> object level allocations. To track object level allocations,
> slabobj_ext consumes 16 bytes per object for profiling slub object if
> CONFIG_MEMCG is set.
> Based on the data I've collected, this overhead accounts for approximately
> 5.7% of slub memory usage — a considerable cost.
> w/ noslub  slub_debug=-
> Slab:              87520 kB
> w/o noslub slub_debug=-
> Slab:              92812 kB
> 
> While In some scenarios, we may choose not to delve into SLUB allocation
> details if initial triage indicates that SLUB memory usage is within
> acceptable limits. To support this, a control knob is introduced to enable
> or disable SLUB object tracking.
> The "noslub" knob disables SLUB tracking, preventing further allocation of
> slabobj_ext structures.

...Have there been actual scenarios where this would be useful?

We've already got a knob for memory allocation profiling as a whole;
most allocations are slub allocations, so if you're looking at memory
allocation profiling you probably want slub.

> 
> Signed-off-by: Zhenhua Huang <quic_zhenhuah@quicinc.com>
> ---
>  Documentation/mm/allocation-profiling.rst |  7 +++++-
>  include/linux/alloc_tag.h                 |  8 +++++++
>  lib/alloc_tag.c                           | 26 +++++++++++++++++------
>  mm/slub.c                                 | 10 ++++-----
>  4 files changed, 38 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/mm/allocation-profiling.rst b/Documentation/mm/allocation-profiling.rst
> index 316311240e6a..9ecae74e0365 100644
> --- a/Documentation/mm/allocation-profiling.rst
> +++ b/Documentation/mm/allocation-profiling.rst
> @@ -18,7 +18,7 @@ kconfig options:
>    missing annotation
>  
>  Boot parameter:
> -  sysctl.vm.mem_profiling={0|1|never}[,compressed]
> +  sysctl.vm.mem_profiling={0|1|never}[,compressed][,noslub]
>  
>    When set to "never", memory allocation profiling overhead is minimized and it
>    cannot be enabled at runtime (sysctl becomes read-only).
> @@ -30,6 +30,11 @@ Boot parameter:
>    If compression fails, a warning is issued and memory allocation profiling gets
>    disabled.
>  
> +  The optional noslub parameter disables tracking of individual SLUB objects. This
> +  approach, similar to how page owner tracking works, relies on slub_debug for SLUB
> +  object insights instead. While this reduces memory overhead, it also limits the
> +  ability to observe detailed SLUB allocation behavior.
> +
>  sysctl:
>    /proc/sys/vm/mem_profiling
>  
> diff --git a/include/linux/alloc_tag.h b/include/linux/alloc_tag.h
> index 8f7931eb7d16..af3c139712ce 100644
> --- a/include/linux/alloc_tag.h
> +++ b/include/linux/alloc_tag.h
> @@ -134,6 +134,13 @@ static inline bool mem_alloc_profiling_enabled(void)
>  				   &mem_alloc_profiling_key);
>  }
>  
> +DECLARE_STATIC_KEY_TRUE(slub_mem_alloc_profiling_key);
> +
> +static inline bool slub_mem_alloc_profiling_enabled(void)
> +{
> +	return static_key_enabled(&slub_mem_alloc_profiling_key);
> +}
> +
>  static inline struct alloc_tag_counters alloc_tag_read(struct alloc_tag *tag)
>  {
>  	struct alloc_tag_counters v = { 0, 0 };
> @@ -227,6 +234,7 @@ static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes)
>  
>  #define DEFINE_ALLOC_TAG(_alloc_tag)
>  static inline bool mem_alloc_profiling_enabled(void) { return false; }
> +static inline bool slub_mem_alloc_profiling_enabled(void) { return false; }
>  static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag,
>  				 size_t bytes) {}
>  static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes) {}
> diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
> index 0142bc916f73..b79b0d987427 100644
> --- a/lib/alloc_tag.c
> +++ b/lib/alloc_tag.c
> @@ -33,6 +33,8 @@ DEFINE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
>  EXPORT_SYMBOL(mem_alloc_profiling_key);
>  
>  DEFINE_STATIC_KEY_FALSE(mem_profiling_compressed);
> +DEFINE_STATIC_KEY_TRUE(slub_mem_alloc_profiling_key);
> +EXPORT_SYMBOL(slub_mem_alloc_profiling_key);
>  
>  struct alloc_tag_kernel_section kernel_tags = { NULL, 0 };
>  unsigned long alloc_tag_ref_mask;
> @@ -710,6 +712,7 @@ static inline void free_mod_tags_mem(void) {}
>  static int __init setup_early_mem_profiling(char *str)
>  {
>  	bool compressed = false;
> +	bool noslub = false;
>  	bool enable;
>  
>  	if (!str || !str[0])
> @@ -725,16 +728,19 @@ static int __init setup_early_mem_profiling(char *str)
>  		if (kstrtobool(token, &enable))
>  			return -EINVAL;
>  
> -		if (str) {
> -
> -			if (strcmp(str, "compressed"))
> +		while ((token = strsep(&str, ",")) != NULL) {
> +			if (strcmp(token, "compressed") == 0)
> +				compressed = true;
> +			else if (strcmp(token, "noslub") == 0)
> +				noslub = true;
> +			else
>  				return -EINVAL;
> -
> -			compressed = true;
>  		}
>  		mem_profiling_support = true;
> -		pr_info("Memory allocation profiling is enabled %s compression and is turned %s!\n",
> -			compressed ? "with" : "without", enable ? "on" : "off");
> +		pr_info("Memory allocation profiling is enabled %s compression, %s slub track and is turned %s!\n",
> +			compressed ? "with" : "without",
> +			noslub ? "without" : "with",
> +			enable ? "on" : "off");
>  	}
>  
>  	if (enable != mem_alloc_profiling_enabled()) {
> @@ -749,6 +755,12 @@ static int __init setup_early_mem_profiling(char *str)
>  		else
>  			static_branch_disable(&mem_profiling_compressed);
>  	}
> +	if (noslub == static_key_enabled(&slub_mem_alloc_profiling_key)) {
> +		if (noslub)
> +			static_branch_disable(&slub_mem_alloc_profiling_key);
> +		else
> +			static_branch_enable(&slub_mem_alloc_profiling_key);
> +	}
>  
>  	return 0;
>  }
> diff --git a/mm/slub.c b/mm/slub.c
> index 31e11ef256f9..e8378b092b30 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2093,7 +2093,7 @@ prepare_slab_obj_exts_hook(struct kmem_cache *s, gfp_t flags, void *p)
>  	return slab_obj_exts(slab) + obj_to_index(s, slab, p);
>  }
>  
> -/* Should be called only if mem_alloc_profiling_enabled() */
> +/* Should be called only if slub_mem_alloc_profiling_enabled() */
>  static noinline void
>  __alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
>  {
> @@ -2102,7 +2102,7 @@ __alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
>  	obj_exts = prepare_slab_obj_exts_hook(s, flags, object);
>  	/*
>  	 * Currently obj_exts is used only for allocation profiling.
> -	 * If other users appear then mem_alloc_profiling_enabled()
> +	 * If other users appear then slub_mem_alloc_profiling_enabled()
>  	 * check should be added before alloc_tag_add().
>  	 */
>  	if (likely(obj_exts))
> @@ -2112,11 +2112,11 @@ __alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
>  static inline void
>  alloc_tagging_slab_alloc_hook(struct kmem_cache *s, void *object, gfp_t flags)
>  {
> -	if (mem_alloc_profiling_enabled())
> +	if (slub_mem_alloc_profiling_enabled())
>  		__alloc_tagging_slab_alloc_hook(s, object, flags);
>  }
>  
> -/* Should be called only if mem_alloc_profiling_enabled() */
> +/* Should be called only if slub_mem_alloc_profiling_enabled() */
>  static noinline void
>  __alloc_tagging_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
>  			       int objects)
> @@ -2143,7 +2143,7 @@ static inline void
>  alloc_tagging_slab_free_hook(struct kmem_cache *s, struct slab *slab, void **p,
>  			     int objects)
>  {
> -	if (mem_alloc_profiling_enabled())
> +	if (slub_mem_alloc_profiling_enabled())
>  		__alloc_tagging_slab_free_hook(s, slab, p, objects);
>  }
>  
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object
  2025-07-23  9:19 ` Harry Yoo
  2025-07-23 10:21   ` Zhenhua Huang
@ 2025-07-23 11:38   ` Kent Overstreet
  2025-07-24  3:29     ` Zhenhua Huang
  1 sibling, 1 reply; 7+ messages in thread
From: Kent Overstreet @ 2025-07-23 11:38 UTC (permalink / raw)
  To: Harry Yoo
  Cc: Zhenhua Huang, rientjes, vbabka, cl, roman.gushchin, surenb,
	pasha.tatashin, akpm, corbet, linux-mm, linux-doc, linux-kernel,
	quic_tingweiz

On Wed, Jul 23, 2025 at 06:19:45PM +0900, Harry Yoo wrote:
> The subject is a bit misleading. I think it should be something like
> "alloc_tag: add an option to disable slab object accounting".
> 
> On Wed, Jul 23, 2025 at 04:03:28PM +0800, Zhenhua Huang wrote:
> > Mem profiling feature tracks both "alloc_slab_page"(page level) and slub
> > object level allocations. To track object level allocations,
> > slabobj_ext consumes 16 bytes per object for profiling slub object if
> > CONFIG_MEMCG is set.
> > Based on the data I've collected, this overhead accounts for approximately
> > 5.7% of slub memory usage — a considerable cost.
> > w/ noslub  slub_debug=-
> > Slab:              87520 kB
> > w/o noslub slub_debug=-
> > Slab:              92812 kB
> 
> Yes, the cost is not small and I hate that we have to pay 16 bytes of
> memory overhead for each slab object when both memcg and memory profiling
> are enabled.

I believe we did something about this for page_obj_ext; the exact
pointer compression scheme we went with escapes me at the moment.

We did it for page and not slab because page_obj_ext is a large fixed
size overhead and the page allocator is slower anyways, but it's
conceivable we could do the same for slub if the memory overhead vs. cpu
overhead tradeoff is worth it.

And - pointer compression is a valuable technique in general; coming up
with some fast general purpose code (perhaps involving virtual mappings,
we're not so limited on virtual address space as we used to be) might be
worth someone's time exploring.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object
  2025-07-23 11:38   ` Kent Overstreet
@ 2025-07-24  3:29     ` Zhenhua Huang
  0 siblings, 0 replies; 7+ messages in thread
From: Zhenhua Huang @ 2025-07-24  3:29 UTC (permalink / raw)
  To: Kent Overstreet, Harry Yoo
  Cc: rientjes, vbabka, cl, roman.gushchin, surenb, pasha.tatashin,
	akpm, corbet, linux-mm, linux-doc, linux-kernel, quic_tingweiz



On 2025/7/23 19:38, Kent Overstreet wrote:
> On Wed, Jul 23, 2025 at 06:19:45PM +0900, Harry Yoo wrote:
>> The subject is a bit misleading. I think it should be something like
>> "alloc_tag: add an option to disable slab object accounting".
>>
>> On Wed, Jul 23, 2025 at 04:03:28PM +0800, Zhenhua Huang wrote:
>>> Mem profiling feature tracks both "alloc_slab_page"(page level) and slub
>>> object level allocations. To track object level allocations,
>>> slabobj_ext consumes 16 bytes per object for profiling slub object if
>>> CONFIG_MEMCG is set.
>>> Based on the data I've collected, this overhead accounts for approximately
>>> 5.7% of slub memory usage — a considerable cost.
>>> w/ noslub  slub_debug=-
>>> Slab:              87520 kB
>>> w/o noslub slub_debug=-
>>> Slab:              92812 kB
>>
>> Yes, the cost is not small and I hate that we have to pay 16 bytes of
>> memory overhead for each slab object when both memcg and memory profiling
>> are enabled.
> 
> I believe we did something about this for page_obj_ext; the exact
> pointer compression scheme we went with escapes me at the moment.
> 

Hi Kent,

I recall that it used page flags for compression — not actual pointers, 
but rather *idx*. Since every page has a corresponding struct page, that 
makes this approach feasible. However, it seems this assumption doesn't 
hold for slab objects.

> We did it for page and not slab because page_obj_ext is a large fixed
> size overhead and the page allocator is slower anyways, but it's
> conceivable we could do the same for slub if the memory overhead vs. cpu
> overhead tradeoff is worth it.
> 
> And - pointer compression is a valuable technique in general; coming up
> with some fast general purpose code (perhaps involving virtual mappings,
> we're not so limited on virtual address space as we used to be) might be
> worth someone's time exploring.
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object
  2025-07-23 11:31 ` Kent Overstreet
@ 2025-07-24  3:57   ` Zhenhua Huang
  0 siblings, 0 replies; 7+ messages in thread
From: Zhenhua Huang @ 2025-07-24  3:57 UTC (permalink / raw)
  To: Kent Overstreet
  Cc: rientjes, vbabka, cl, roman.gushchin, harry.yoo, surenb,
	pasha.tatashin, akpm, corbet, linux-mm, linux-doc, linux-kernel,
	quic_tingweiz



On 2025/7/23 19:31, Kent Overstreet wrote:
>> While In some scenarios, we may choose not to delve into SLUB allocation
>> details if initial triage indicates that SLUB memory usage is within
>> acceptable limits. To support this, a control knob is introduced to enable
>> or disable SLUB object tracking.
>> The "noslub" knob disables SLUB tracking, preventing further allocation of
>> slabobj_ext structures.
> ...Have there been actual scenarios where this would be useful?
> 
> We've already got a knob for memory allocation profiling as a whole;
> most allocations are slub allocations, so if you're looking at memory
> allocation profiling you probably want slub.

Hi Kent,

Let me elaborate a bit on the work we're doing. Some OEMs are interested 
in enabling this lightweight debug feature to help identify potential 
memory leaks on their devices. In the past, we depended on mechanisms 
such as page owner for tracking, but due to their overhead, they were 
not suitable for deployment on production devices. In response, our team 
is developing a post-processing script(may need to parse source code as 
well)—to classify memory usage accordingly.

One output example FYI:
version: 1.0
MemInfo                        :    Size_KB    Size_MB
slab                           :     440088     429.77
vmalloc                        :      71416      69.74
pgd                            :        888       0.87
pte                            :     104492     102.04
pmd                            :      12732      12.43
pageowner                      :     437760     427.50
module                         :          0       0.00
kernelStack                    :      54346      53.07
shmem                          :      18284      17.86
KDA                            :     188516     184.10
anon                           :     867120     846.80
ion                            :     420576     410.72
kgsl                           :      70328      68.68
CMA                            :     130992     127.92
file                           :    2037140    1989.39
zram                           :     156532     152.86
binder                         :          0       0.00
migrate                        :          0       0.00
Couldn't Parse                 :         17       0.02
slab_alone                     :     478939     467.71

In this case, we may not need to dive into slab-level details. Instead, 
our initial focus should be on checking KDA(that is, pages that are 
allocated but not tracked by any statistics). In other words, for a 
quick snapshot, it's unnecessary to analyze slab internals. If we need 
to debug specific slab leaks, we can even afford to enable slab_debug=U.

The key requirement is to make this feature suitable for deployment in 
production devices, as requested by OEMs. The 16-byte per-object 
overhead represents the highest cost in its current form, and we are 
exploring options to optimize it.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-07-24  3:58 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-23  8:03 [PATCH 1/1] mm: slub: Introduce one knob to control the track of slub object Zhenhua Huang
2025-07-23  9:19 ` Harry Yoo
2025-07-23 10:21   ` Zhenhua Huang
2025-07-23 11:38   ` Kent Overstreet
2025-07-24  3:29     ` Zhenhua Huang
2025-07-23 11:31 ` Kent Overstreet
2025-07-24  3:57   ` Zhenhua Huang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).