* [PATCH v5 1/4] mm: khugepaged: export set_recommended_min_free_kbytes()
2026-03-10 17:57 [PATCH v5 0/4] mm: thp: reduce unnecessary start_stop_khugepaged() calls Breno Leitao
@ 2026-03-10 17:57 ` Breno Leitao
2026-03-10 18:32 ` Zi Yan
2026-03-10 17:57 ` [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders() Breno Leitao
` (2 subsequent siblings)
3 siblings, 1 reply; 18+ messages in thread
From: Breno Leitao @ 2026-03-10 17:57 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport
Cc: linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle), Breno Leitao
Make set_recommended_min_free_kbytes() callable from outside
khugepaged.c by removing the static qualifier and adding a
declaration in mm/internal.h.
This allows callers that change THP settings to recalculate
watermarks without going through start_stop_khugepaged().
Suggested-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
mm/internal.h | 5 +++++
mm/khugepaged.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/mm/internal.h b/mm/internal.h
index cb0af847d7d99..7bd768e367793 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -623,6 +623,11 @@ int user_proactive_reclaim(char *buf,
*/
pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address);
+/*
+ * in mm/khugepaged.c
+ */
+void set_recommended_min_free_kbytes(void);
+
/*
* in mm/page_alloc.c
*/
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 1dd3cfca610db..56a41c21b44c9 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2630,7 +2630,7 @@ static int khugepaged(void *none)
return 0;
}
-static void set_recommended_min_free_kbytes(void)
+void set_recommended_min_free_kbytes(void)
{
struct zone *zone;
int nr_zones = 0;
--
2.52.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v5 1/4] mm: khugepaged: export set_recommended_min_free_kbytes()
2026-03-10 17:57 ` [PATCH v5 1/4] mm: khugepaged: export set_recommended_min_free_kbytes() Breno Leitao
@ 2026-03-10 18:32 ` Zi Yan
0 siblings, 0 replies; 18+ messages in thread
From: Zi Yan @ 2026-03-10 18:32 UTC (permalink / raw)
To: Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On 10 Mar 2026, at 13:57, Breno Leitao wrote:
> Make set_recommended_min_free_kbytes() callable from outside
> khugepaged.c by removing the static qualifier and adding a
> declaration in mm/internal.h.
>
> This allows callers that change THP settings to recalculate
> watermarks without going through start_stop_khugepaged().
>
> Suggested-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
> mm/internal.h | 5 +++++
> mm/khugepaged.c | 2 +-
> 2 files changed, 6 insertions(+), 1 deletion(-)
>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-10 17:57 [PATCH v5 0/4] mm: thp: reduce unnecessary start_stop_khugepaged() calls Breno Leitao
2026-03-10 17:57 ` [PATCH v5 1/4] mm: khugepaged: export set_recommended_min_free_kbytes() Breno Leitao
@ 2026-03-10 17:57 ` Breno Leitao
2026-03-10 18:38 ` Zi Yan
` (3 more replies)
2026-03-10 17:57 ` [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled() Breno Leitao
2026-03-10 17:57 ` [PATCH v5 4/4] mm: ratelimit min_free_kbytes adjustment messages Breno Leitao
3 siblings, 4 replies; 18+ messages in thread
From: Breno Leitao @ 2026-03-10 17:57 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport
Cc: linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Breno Leitao, Lorenzo Stoakes (Oracle)
Consolidate the repeated spin_lock/set_bit/clear_bit pattern in
anon_enabled_store() into a new change_anon_orders() helper that
loops over an orders[] array, setting the bit for the selected mode
and clearing the others.
Introduce enum anon_enabled_mode and anon_enabled_mode_strings[]
for the per-order anon THP setting.
Use sysfs_match_string() with the anon_enabled_mode_strings[] table
to replace the if/else chain of sysfs_streq() calls.
The helper uses test_and_set_bit()/test_and_clear_bit() to track
whether the state actually changed, so start_stop_khugepaged() is
only called when needed. When the mode is unchanged,
set_recommended_min_free_kbytes() is called directly to preserve
the watermark recalculation behavior of the original code.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
---
mm/huge_memory.c | 84 +++++++++++++++++++++++++++++++++++---------------------
1 file changed, 52 insertions(+), 32 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 8e2746ea74adf..e19dda5aaf195 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -316,6 +316,20 @@ static ssize_t enabled_show(struct kobject *kobj,
return sysfs_emit(buf, "%s\n", output);
}
+enum anon_enabled_mode {
+ ANON_ENABLED_ALWAYS = 0,
+ ANON_ENABLED_MADVISE = 1,
+ ANON_ENABLED_INHERIT = 2,
+ ANON_ENABLED_NEVER = 3,
+};
+
+static const char * const anon_enabled_mode_strings[] = {
+ [ANON_ENABLED_ALWAYS] = "always",
+ [ANON_ENABLED_MADVISE] = "madvise",
+ [ANON_ENABLED_INHERIT] = "inherit",
+ [ANON_ENABLED_NEVER] = "never",
+};
+
static ssize_t enabled_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
@@ -515,48 +529,54 @@ static ssize_t anon_enabled_show(struct kobject *kobj,
return sysfs_emit(buf, "%s\n", output);
}
+static bool set_anon_enabled_mode(int order, enum anon_enabled_mode mode)
+{
+ static unsigned long *enabled_orders[] = {
+ &huge_anon_orders_always,
+ &huge_anon_orders_madvise,
+ &huge_anon_orders_inherit,
+ };
+ enum anon_enabled_mode m;
+ bool changed = false;
+
+ spin_lock(&huge_anon_orders_lock);
+ for (m = 0; m < ARRAY_SIZE(enabled_orders); m++) {
+ if (m == mode)
+ changed |= !__test_and_set_bit(order, enabled_orders[m]);
+ else
+ changed |= __test_and_clear_bit(order, enabled_orders[m]);
+ }
+ spin_unlock(&huge_anon_orders_lock);
+
+ return changed;
+}
+
static ssize_t anon_enabled_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int order = to_thpsize(kobj)->order;
- ssize_t ret = count;
+ int mode;
- if (sysfs_streq(buf, "always")) {
- spin_lock(&huge_anon_orders_lock);
- clear_bit(order, &huge_anon_orders_inherit);
- clear_bit(order, &huge_anon_orders_madvise);
- set_bit(order, &huge_anon_orders_always);
- spin_unlock(&huge_anon_orders_lock);
- } else if (sysfs_streq(buf, "inherit")) {
- spin_lock(&huge_anon_orders_lock);
- clear_bit(order, &huge_anon_orders_always);
- clear_bit(order, &huge_anon_orders_madvise);
- set_bit(order, &huge_anon_orders_inherit);
- spin_unlock(&huge_anon_orders_lock);
- } else if (sysfs_streq(buf, "madvise")) {
- spin_lock(&huge_anon_orders_lock);
- clear_bit(order, &huge_anon_orders_always);
- clear_bit(order, &huge_anon_orders_inherit);
- set_bit(order, &huge_anon_orders_madvise);
- spin_unlock(&huge_anon_orders_lock);
- } else if (sysfs_streq(buf, "never")) {
- spin_lock(&huge_anon_orders_lock);
- clear_bit(order, &huge_anon_orders_always);
- clear_bit(order, &huge_anon_orders_inherit);
- clear_bit(order, &huge_anon_orders_madvise);
- spin_unlock(&huge_anon_orders_lock);
- } else
- ret = -EINVAL;
+ mode = sysfs_match_string(anon_enabled_mode_strings, buf);
+ if (mode < 0)
+ return -EINVAL;
- if (ret > 0) {
- int err;
+ if (set_anon_enabled_mode(order, mode)) {
+ int err = start_stop_khugepaged();
- err = start_stop_khugepaged();
if (err)
- ret = err;
+ return err;
+ } else {
+ /*
+ * Recalculate watermarks even when the mode didn't
+ * change, as the previous code always called
+ * start_stop_khugepaged() which does this internally.
+ */
+ set_recommended_min_free_kbytes();
}
- return ret;
+
+ return count;
}
static struct kobj_attribute anon_enabled_attr =
--
2.52.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-10 17:57 ` [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders() Breno Leitao
@ 2026-03-10 18:38 ` Zi Yan
2026-03-10 20:11 ` Barry Song
` (2 subsequent siblings)
3 siblings, 0 replies; 18+ messages in thread
From: Zi Yan @ 2026-03-10 18:38 UTC (permalink / raw)
To: Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On 10 Mar 2026, at 13:57, Breno Leitao wrote:
> Consolidate the repeated spin_lock/set_bit/clear_bit pattern in
> anon_enabled_store() into a new change_anon_orders() helper that
> loops over an orders[] array, setting the bit for the selected mode
> and clearing the others.
>
> Introduce enum anon_enabled_mode and anon_enabled_mode_strings[]
> for the per-order anon THP setting.
>
> Use sysfs_match_string() with the anon_enabled_mode_strings[] table
> to replace the if/else chain of sysfs_streq() calls.
>
> The helper uses test_and_set_bit()/test_and_clear_bit() to track
> whether the state actually changed, so start_stop_khugepaged() is
> only called when needed. When the mode is unchanged,
> set_recommended_min_free_kbytes() is called directly to preserve
> the watermark recalculation behavior of the original code.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
> mm/huge_memory.c | 84 +++++++++++++++++++++++++++++++++++---------------------
> 1 file changed, 52 insertions(+), 32 deletions(-)
>
Nice cleanup.
Reviewed-by: Zi Yan <ziy@nvidia.com>
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-10 17:57 ` [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders() Breno Leitao
2026-03-10 18:38 ` Zi Yan
@ 2026-03-10 20:11 ` Barry Song
2026-03-10 20:17 ` Andrew Morton
2026-03-11 1:37 ` Baolin Wang
2026-03-11 3:12 ` Wei Yang
3 siblings, 1 reply; 18+ messages in thread
From: Barry Song @ 2026-03-10 20:11 UTC (permalink / raw)
To: Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Lance Yang, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On Wed, Mar 11, 2026 at 1:58 AM Breno Leitao <leitao@debian.org> wrote:
>
> Consolidate the repeated spin_lock/set_bit/clear_bit pattern in
> anon_enabled_store() into a new change_anon_orders() helper that
> loops over an orders[] array, setting the bit for the selected mode
> and clearing the others.
>
> Introduce enum anon_enabled_mode and anon_enabled_mode_strings[]
> for the per-order anon THP setting.
>
> Use sysfs_match_string() with the anon_enabled_mode_strings[] table
> to replace the if/else chain of sysfs_streq() calls.
>
> The helper uses test_and_set_bit()/test_and_clear_bit() to track
> whether the state actually changed, so start_stop_khugepaged() is
> only called when needed. When the mode is unchanged,
> set_recommended_min_free_kbytes() is called directly to preserve
> the watermark recalculation behavior of the original code.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
> mm/huge_memory.c | 84 +++++++++++++++++++++++++++++++++++---------------------
> 1 file changed, 52 insertions(+), 32 deletions(-)
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 8e2746ea74adf..e19dda5aaf195 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -316,6 +316,20 @@ static ssize_t enabled_show(struct kobject *kobj,
> return sysfs_emit(buf, "%s\n", output);
> }
>
> +enum anon_enabled_mode {
> + ANON_ENABLED_ALWAYS = 0,
> + ANON_ENABLED_MADVISE = 1,
> + ANON_ENABLED_INHERIT = 2,
> + ANON_ENABLED_NEVER = 3,
> +};
> +
> +static const char * const anon_enabled_mode_strings[] = {
> + [ANON_ENABLED_ALWAYS] = "always",
> + [ANON_ENABLED_MADVISE] = "madvise",
> + [ANON_ENABLED_INHERIT] = "inherit",
> + [ANON_ENABLED_NEVER] = "never",
> +};
Do we really need anon_enabled_mode here? Would it be ok
to just use ...
static const char * const anon_enabled_mode_strings[] = {
"always", "madvise", "inherit", "never",
};
Nobody else cares about the values like ANON_ENABLED_ALWAYS
except the sysfs interface, right? Maybe we don't need to
force people to understand the enum.
> +
> static ssize_t enabled_store(struct kobject *kobj,
> struct kobj_attribute *attr,
> const char *buf, size_t count)
> @@ -515,48 +529,54 @@ static ssize_t anon_enabled_show(struct kobject *kobj,
> return sysfs_emit(buf, "%s\n", output);
> }
>
> +static bool set_anon_enabled_mode(int order, enum anon_enabled_mode mode)
> +{
> + static unsigned long *enabled_orders[] = {
> + &huge_anon_orders_always,
> + &huge_anon_orders_madvise,
> + &huge_anon_orders_inherit,
> + };
Is there a reason enabled_orders needs to be static?
Could it instead be allocated on the stack?
Thanks
Barry
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-10 20:11 ` Barry Song
@ 2026-03-10 20:17 ` Andrew Morton
2026-03-10 20:22 ` Barry Song
0 siblings, 1 reply; 18+ messages in thread
From: Andrew Morton @ 2026-03-10 20:17 UTC (permalink / raw)
To: Barry Song
Cc: Breno Leitao, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Lance Yang, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On Wed, 11 Mar 2026 04:11:36 +0800 Barry Song <21cnbao@gmail.com> wrote:
> > +static bool set_anon_enabled_mode(int order, enum anon_enabled_mode mode)
> > +{
> > + static unsigned long *enabled_orders[] = {
> > + &huge_anon_orders_always,
> > + &huge_anon_orders_madvise,
> > + &huge_anon_orders_inherit,
> > + };
>
> Is there a reason enabled_orders needs to be static?
> Could it instead be allocated on the stack?
Could, but then the array would be rebuilt each time the function is called.
The idea here is to save a bit of runtime cost.
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-10 20:17 ` Andrew Morton
@ 2026-03-10 20:22 ` Barry Song
0 siblings, 0 replies; 18+ messages in thread
From: Barry Song @ 2026-03-10 20:22 UTC (permalink / raw)
To: Andrew Morton
Cc: Breno Leitao, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Lance Yang, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On Wed, Mar 11, 2026 at 4:17 AM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Wed, 11 Mar 2026 04:11:36 +0800 Barry Song <21cnbao@gmail.com> wrote:
>
> > > +static bool set_anon_enabled_mode(int order, enum anon_enabled_mode mode)
> > > +{
> > > + static unsigned long *enabled_orders[] = {
> > > + &huge_anon_orders_always,
> > > + &huge_anon_orders_madvise,
> > > + &huge_anon_orders_inherit,
> > > + };
> >
> > Is there a reason enabled_orders needs to be static?
> > Could it instead be allocated on the stack?
>
> Could, but then the array would be rebuilt each time the function is called.
> The idea here is to save a bit of runtime cost.
I see. My understanding is that this function is very cold,
so we don't really care about its performance. But I'm fine
with keeping it static if you prefer.
Thanks
Barry
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-10 17:57 ` [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders() Breno Leitao
2026-03-10 18:38 ` Zi Yan
2026-03-10 20:11 ` Barry Song
@ 2026-03-11 1:37 ` Baolin Wang
2026-03-11 3:12 ` Wei Yang
3 siblings, 0 replies; 18+ messages in thread
From: Baolin Wang @ 2026-03-11 1:37 UTC (permalink / raw)
To: Breno Leitao, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Zi Yan, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport
Cc: linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On 3/11/26 1:57 AM, Breno Leitao wrote:
> Consolidate the repeated spin_lock/set_bit/clear_bit pattern in
> anon_enabled_store() into a new change_anon_orders() helper that
> loops over an orders[] array, setting the bit for the selected mode
> and clearing the others.
>
> Introduce enum anon_enabled_mode and anon_enabled_mode_strings[]
> for the per-order anon THP setting.
>
> Use sysfs_match_string() with the anon_enabled_mode_strings[] table
> to replace the if/else chain of sysfs_streq() calls.
>
> The helper uses test_and_set_bit()/test_and_clear_bit() to track
> whether the state actually changed, so start_stop_khugepaged() is
> only called when needed. When the mode is unchanged,
> set_recommended_min_free_kbytes() is called directly to preserve
> the watermark recalculation behavior of the original code.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
LGTM.
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-10 17:57 ` [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders() Breno Leitao
` (2 preceding siblings ...)
2026-03-11 1:37 ` Baolin Wang
@ 2026-03-11 3:12 ` Wei Yang
2026-03-11 4:52 ` Lance Yang
3 siblings, 1 reply; 18+ messages in thread
From: Wei Yang @ 2026-03-11 3:12 UTC (permalink / raw)
To: Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport,
linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On Tue, Mar 10, 2026 at 10:57:08AM -0700, Breno Leitao wrote:
>Consolidate the repeated spin_lock/set_bit/clear_bit pattern in
>anon_enabled_store() into a new change_anon_orders() helper that
>loops over an orders[] array, setting the bit for the selected mode
>and clearing the others.
>
>Introduce enum anon_enabled_mode and anon_enabled_mode_strings[]
>for the per-order anon THP setting.
>
>Use sysfs_match_string() with the anon_enabled_mode_strings[] table
>to replace the if/else chain of sysfs_streq() calls.
>
>The helper uses test_and_set_bit()/test_and_clear_bit() to track
>whether the state actually changed, so start_stop_khugepaged() is
>only called when needed. When the mode is unchanged,
>set_recommended_min_free_kbytes() is called directly to preserve
>the watermark recalculation behavior of the original code.
>
>Signed-off-by: Breno Leitao <leitao@debian.org>
>Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
>---
> mm/huge_memory.c | 84 +++++++++++++++++++++++++++++++++++---------------------
> 1 file changed, 52 insertions(+), 32 deletions(-)
>
>diff --git a/mm/huge_memory.c b/mm/huge_memory.c
>index 8e2746ea74adf..e19dda5aaf195 100644
>--- a/mm/huge_memory.c
>+++ b/mm/huge_memory.c
>@@ -316,6 +316,20 @@ static ssize_t enabled_show(struct kobject *kobj,
> return sysfs_emit(buf, "%s\n", output);
> }
>
>+enum anon_enabled_mode {
>+ ANON_ENABLED_ALWAYS = 0,
>+ ANON_ENABLED_MADVISE = 1,
>+ ANON_ENABLED_INHERIT = 2,
>+ ANON_ENABLED_NEVER = 3,
>+};
>+
>+static const char * const anon_enabled_mode_strings[] = {
>+ [ANON_ENABLED_ALWAYS] = "always",
>+ [ANON_ENABLED_MADVISE] = "madvise",
>+ [ANON_ENABLED_INHERIT] = "inherit",
>+ [ANON_ENABLED_NEVER] = "never",
>+};
>+
Just one trivial thing, maybe keep the sequence as the sysfs output?
Currently the output of /sys/kernel/transparent_hugepage/hugepages-xxxkB is
always inherit madvise [never]
But no strong opinion on this.
> static ssize_t enabled_store(struct kobject *kobj,
> struct kobj_attribute *attr,
> const char *buf, size_t count)
>@@ -515,48 +529,54 @@ static ssize_t anon_enabled_show(struct kobject *kobj,
> return sysfs_emit(buf, "%s\n", output);
> }
>
>+static bool set_anon_enabled_mode(int order, enum anon_enabled_mode mode)
>+{
>+ static unsigned long *enabled_orders[] = {
>+ &huge_anon_orders_always,
>+ &huge_anon_orders_madvise,
>+ &huge_anon_orders_inherit,
>+ };
>+ enum anon_enabled_mode m;
>+ bool changed = false;
>+
>+ spin_lock(&huge_anon_orders_lock);
>+ for (m = 0; m < ARRAY_SIZE(enabled_orders); m++) {
>+ if (m == mode)
>+ changed |= !__test_and_set_bit(order, enabled_orders[m]);
>+ else
>+ changed |= __test_and_clear_bit(order, enabled_orders[m]);
>+ }
>+ spin_unlock(&huge_anon_orders_lock);
>+
>+ return changed;
>+}
>+
Nice cleanup, so
Reviewed-by: Wei Yang <richard.weiyang@gmail.com>
> static ssize_t anon_enabled_store(struct kobject *kobj,
> struct kobj_attribute *attr,
> const char *buf, size_t count)
> {
> int order = to_thpsize(kobj)->order;
>- ssize_t ret = count;
>+ int mode;
>
>- if (sysfs_streq(buf, "always")) {
>- spin_lock(&huge_anon_orders_lock);
>- clear_bit(order, &huge_anon_orders_inherit);
>- clear_bit(order, &huge_anon_orders_madvise);
>- set_bit(order, &huge_anon_orders_always);
>- spin_unlock(&huge_anon_orders_lock);
>- } else if (sysfs_streq(buf, "inherit")) {
>- spin_lock(&huge_anon_orders_lock);
>- clear_bit(order, &huge_anon_orders_always);
>- clear_bit(order, &huge_anon_orders_madvise);
>- set_bit(order, &huge_anon_orders_inherit);
>- spin_unlock(&huge_anon_orders_lock);
>- } else if (sysfs_streq(buf, "madvise")) {
>- spin_lock(&huge_anon_orders_lock);
>- clear_bit(order, &huge_anon_orders_always);
>- clear_bit(order, &huge_anon_orders_inherit);
>- set_bit(order, &huge_anon_orders_madvise);
>- spin_unlock(&huge_anon_orders_lock);
>- } else if (sysfs_streq(buf, "never")) {
>- spin_lock(&huge_anon_orders_lock);
>- clear_bit(order, &huge_anon_orders_always);
>- clear_bit(order, &huge_anon_orders_inherit);
>- clear_bit(order, &huge_anon_orders_madvise);
>- spin_unlock(&huge_anon_orders_lock);
>- } else
>- ret = -EINVAL;
>+ mode = sysfs_match_string(anon_enabled_mode_strings, buf);
>+ if (mode < 0)
>+ return -EINVAL;
>
>- if (ret > 0) {
>- int err;
>+ if (set_anon_enabled_mode(order, mode)) {
>+ int err = start_stop_khugepaged();
>
>- err = start_stop_khugepaged();
> if (err)
>- ret = err;
>+ return err;
>+ } else {
>+ /*
>+ * Recalculate watermarks even when the mode didn't
>+ * change, as the previous code always called
>+ * start_stop_khugepaged() which does this internally.
>+ */
>+ set_recommended_min_free_kbytes();
> }
>- return ret;
>+
>+ return count;
> }
>
> static struct kobj_attribute anon_enabled_attr =
>
>--
>2.52.0
>
--
Wei Yang
Help you, Help me
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-11 3:12 ` Wei Yang
@ 2026-03-11 4:52 ` Lance Yang
2026-03-11 9:26 ` Breno Leitao
0 siblings, 1 reply; 18+ messages in thread
From: Lance Yang @ 2026-03-11 4:52 UTC (permalink / raw)
To: Wei Yang, Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On 2026/3/11 11:12, Wei Yang wrote:
> On Tue, Mar 10, 2026 at 10:57:08AM -0700, Breno Leitao wrote:
>> Consolidate the repeated spin_lock/set_bit/clear_bit pattern in
>> anon_enabled_store() into a new change_anon_orders() helper that
>> loops over an orders[] array, setting the bit for the selected mode
>> and clearing the others.
>>
>> Introduce enum anon_enabled_mode and anon_enabled_mode_strings[]
>> for the per-order anon THP setting.
>>
>> Use sysfs_match_string() with the anon_enabled_mode_strings[] table
>> to replace the if/else chain of sysfs_streq() calls.
>>
>> The helper uses test_and_set_bit()/test_and_clear_bit() to track
>> whether the state actually changed, so start_stop_khugepaged() is
>> only called when needed. When the mode is unchanged,
>> set_recommended_min_free_kbytes() is called directly to preserve
>> the watermark recalculation behavior of the original code.
>>
>> Signed-off-by: Breno Leitao <leitao@debian.org>
>> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
>> ---
>> mm/huge_memory.c | 84 +++++++++++++++++++++++++++++++++++---------------------
>> 1 file changed, 52 insertions(+), 32 deletions(-)
>>
>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
>> index 8e2746ea74adf..e19dda5aaf195 100644
>> --- a/mm/huge_memory.c
>> +++ b/mm/huge_memory.c
>> @@ -316,6 +316,20 @@ static ssize_t enabled_show(struct kobject *kobj,
>> return sysfs_emit(buf, "%s\n", output);
>> }
>>
>> +enum anon_enabled_mode {
>> + ANON_ENABLED_ALWAYS = 0,
>> + ANON_ENABLED_MADVISE = 1,
>> + ANON_ENABLED_INHERIT = 2,
>> + ANON_ENABLED_NEVER = 3,
>> +};
>> +
>> +static const char * const anon_enabled_mode_strings[] = {
>> + [ANON_ENABLED_ALWAYS] = "always",
>> + [ANON_ENABLED_MADVISE] = "madvise",
>> + [ANON_ENABLED_INHERIT] = "inherit",
>> + [ANON_ENABLED_NEVER] = "never",
>> +};
>> +
>
> Just one trivial thing, maybe keep the sequence as the sysfs output?
>
> Currently the output of /sys/kernel/transparent_hugepage/hugepages-xxxkB is
>
> always inherit madvise [never]
>
> But no strong opinion on this.
Yeah, keeping the enum order consistent with the sysfs output looks
sensible :)
Apart from that, LGTM.
Reviewed-by: Lance Yang <lance.yang@linux.dev>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()
2026-03-11 4:52 ` Lance Yang
@ 2026-03-11 9:26 ` Breno Leitao
0 siblings, 0 replies; 18+ messages in thread
From: Breno Leitao @ 2026-03-11 9:26 UTC (permalink / raw)
To: Lance Yang
Cc: Wei Yang, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Zi Yan, Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts,
Dev Jain, Barry Song, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport,
linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On Wed, Mar 11, 2026 at 12:52:02PM +0800, Lance Yang wrote:
> On 2026/3/11 11:12, Wei Yang wrote:
> > On Tue, Mar 10, 2026 at 10:57:08AM -0700, Breno Leitao wrote:
> > > +enum anon_enabled_mode {
> > > + ANON_ENABLED_ALWAYS = 0,
> > > + ANON_ENABLED_MADVISE = 1,
> > > + ANON_ENABLED_INHERIT = 2,
> > > + ANON_ENABLED_NEVER = 3,
> > > +};
> > > +
> > > +static const char * const anon_enabled_mode_strings[] = {
> > > + [ANON_ENABLED_ALWAYS] = "always",
> > > + [ANON_ENABLED_MADVISE] = "madvise",
> > > + [ANON_ENABLED_INHERIT] = "inherit",
> > > + [ANON_ENABLED_NEVER] = "never",
> > > +};
> > > +
> >
> > Just one trivial thing, maybe keep the sequence as the sysfs output?
> >
> > Currently the output of /sys/kernel/transparent_hugepage/hugepages-xxxkB is
> >
> > always inherit madvise [never]
> >
> > But no strong opinion on this.
>
> Yeah, keeping the enum order consistent with the sysfs output looks sensible
> :)
Good point, I'll adjust the order to match the sysfs output and send out
a new version.
Thanks for the feedback!
--breno
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled()
2026-03-10 17:57 [PATCH v5 0/4] mm: thp: reduce unnecessary start_stop_khugepaged() calls Breno Leitao
2026-03-10 17:57 ` [PATCH v5 1/4] mm: khugepaged: export set_recommended_min_free_kbytes() Breno Leitao
2026-03-10 17:57 ` [PATCH v5 2/4] mm: huge_memory: refactor anon_enabled_store() with change_anon_orders() Breno Leitao
@ 2026-03-10 17:57 ` Breno Leitao
2026-03-10 18:40 ` Zi Yan
` (2 more replies)
2026-03-10 17:57 ` [PATCH v5 4/4] mm: ratelimit min_free_kbytes adjustment messages Breno Leitao
3 siblings, 3 replies; 18+ messages in thread
From: Breno Leitao @ 2026-03-10 17:57 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport
Cc: linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Breno Leitao, Lorenzo Stoakes (Oracle)
Refactor enabled_store() to use a new change_enabled() helper.
Introduce a separate enum global_enabled_mode and
global_enabled_mode_strings[], mirroring the anon_enabled_mode
pattern from the previous commit.
A separate enum is necessary because the global THP setting does
not support "inherit", only "always", "madvise", and "never".
Reusing anon_enabled_mode would leave a NULL gap in the string
array, causing sysfs_match_string() to stop early and fail to
match entries after the gap.
The helper uses the same loop pattern as set_anon_enabled_mode(),
iterating over an array of flag bit positions and using
__test_and_set_bit()/__test_and_clear_bit() to track whether the state
actually changed.
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
---
mm/huge_memory.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 48 insertions(+), 15 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index e19dda5aaf195..cc98a3b8bc247 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -330,30 +330,63 @@ static const char * const anon_enabled_mode_strings[] = {
[ANON_ENABLED_NEVER] = "never",
};
+enum global_enabled_mode {
+ GLOBAL_ENABLED_ALWAYS = 0,
+ GLOBAL_ENABLED_MADVISE = 1,
+ GLOBAL_ENABLED_NEVER = 2,
+};
+
+static const char * const global_enabled_mode_strings[] = {
+ [GLOBAL_ENABLED_ALWAYS] = "always",
+ [GLOBAL_ENABLED_MADVISE] = "madvise",
+ [GLOBAL_ENABLED_NEVER] = "never",
+};
+
+static bool set_global_enabled_mode(enum global_enabled_mode mode)
+{
+ static const unsigned long thp_flags[] = {
+ TRANSPARENT_HUGEPAGE_FLAG,
+ TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG,
+ };
+ enum global_enabled_mode m;
+ bool changed = false;
+
+ for (m = 0; m < ARRAY_SIZE(thp_flags); m++) {
+ if (m == mode)
+ changed |= !__test_and_set_bit(thp_flags[m],
+ &transparent_hugepage_flags);
+ else
+ changed |= __test_and_clear_bit(thp_flags[m],
+ &transparent_hugepage_flags);
+ }
+
+ return changed;
+}
+
static ssize_t enabled_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
- ssize_t ret = count;
+ int mode;
- if (sysfs_streq(buf, "always")) {
- clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags);
- set_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags);
- } else if (sysfs_streq(buf, "madvise")) {
- clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags);
- set_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags);
- } else if (sysfs_streq(buf, "never")) {
- clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags);
- clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags);
- } else
- ret = -EINVAL;
+ mode = sysfs_match_string(global_enabled_mode_strings, buf);
+ if (mode < 0)
+ return -EINVAL;
- if (ret > 0) {
+ if (set_global_enabled_mode(mode)) {
int err = start_stop_khugepaged();
+
if (err)
- ret = err;
+ return err;
+ } else {
+ /*
+ * Recalculate watermarks even when the mode didn't
+ * change, as the previous code always called
+ * start_stop_khugepaged() which does this internally.
+ */
+ set_recommended_min_free_kbytes();
}
- return ret;
+ return count;
}
static struct kobj_attribute enabled_attr = __ATTR_RW(enabled);
--
2.52.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled()
2026-03-10 17:57 ` [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled() Breno Leitao
@ 2026-03-10 18:40 ` Zi Yan
2026-03-11 1:39 ` Baolin Wang
2026-03-11 3:13 ` Wei Yang
2 siblings, 0 replies; 18+ messages in thread
From: Zi Yan @ 2026-03-10 18:40 UTC (permalink / raw)
To: Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On 10 Mar 2026, at 13:57, Breno Leitao wrote:
> Refactor enabled_store() to use a new change_enabled() helper.
> Introduce a separate enum global_enabled_mode and
> global_enabled_mode_strings[], mirroring the anon_enabled_mode
> pattern from the previous commit.
>
> A separate enum is necessary because the global THP setting does
> not support "inherit", only "always", "madvise", and "never".
> Reusing anon_enabled_mode would leave a NULL gap in the string
> array, causing sysfs_match_string() to stop early and fail to
> match entries after the gap.
>
> The helper uses the same loop pattern as set_anon_enabled_mode(),
> iterating over an array of flag bit positions and using
> __test_and_set_bit()/__test_and_clear_bit() to track whether the state
> actually changed.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
> mm/huge_memory.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 48 insertions(+), 15 deletions(-)
>
Nice cleanup.
Reviewed-by: Zi Yan <ziy@nvidia.com>
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled()
2026-03-10 17:57 ` [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled() Breno Leitao
2026-03-10 18:40 ` Zi Yan
@ 2026-03-11 1:39 ` Baolin Wang
2026-03-11 3:13 ` Wei Yang
2 siblings, 0 replies; 18+ messages in thread
From: Baolin Wang @ 2026-03-11 1:39 UTC (permalink / raw)
To: Breno Leitao, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Zi Yan, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport
Cc: linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On 3/11/26 1:57 AM, Breno Leitao wrote:
> Refactor enabled_store() to use a new change_enabled() helper.
> Introduce a separate enum global_enabled_mode and
> global_enabled_mode_strings[], mirroring the anon_enabled_mode
> pattern from the previous commit.
>
> A separate enum is necessary because the global THP setting does
> not support "inherit", only "always", "madvise", and "never".
> Reusing anon_enabled_mode would leave a NULL gap in the string
> array, causing sysfs_match_string() to stop early and fail to
> match entries after the gap.
>
> The helper uses the same loop pattern as set_anon_enabled_mode(),
> iterating over an array of flag bit positions and using
> __test_and_set_bit()/__test_and_clear_bit() to track whether the state
> actually changed.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> ---
LGTM.
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled()
2026-03-10 17:57 ` [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled() Breno Leitao
2026-03-10 18:40 ` Zi Yan
2026-03-11 1:39 ` Baolin Wang
@ 2026-03-11 3:13 ` Wei Yang
2 siblings, 0 replies; 18+ messages in thread
From: Wei Yang @ 2026-03-11 3:13 UTC (permalink / raw)
To: Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport,
linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On Tue, Mar 10, 2026 at 10:57:09AM -0700, Breno Leitao wrote:
>Refactor enabled_store() to use a new change_enabled() helper.
>Introduce a separate enum global_enabled_mode and
>global_enabled_mode_strings[], mirroring the anon_enabled_mode
>pattern from the previous commit.
>
>A separate enum is necessary because the global THP setting does
>not support "inherit", only "always", "madvise", and "never".
>Reusing anon_enabled_mode would leave a NULL gap in the string
>array, causing sysfs_match_string() to stop early and fail to
>match entries after the gap.
>
>The helper uses the same loop pattern as set_anon_enabled_mode(),
>iterating over an array of flag bit positions and using
>__test_and_set_bit()/__test_and_clear_bit() to track whether the state
>actually changed.
>
>Signed-off-by: Breno Leitao <leitao@debian.org>
>Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Reviewed-by: Wei Yang <richard.weiyang@gmail.com>
--
Wei Yang
Help you, Help me
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v5 4/4] mm: ratelimit min_free_kbytes adjustment messages
2026-03-10 17:57 [PATCH v5 0/4] mm: thp: reduce unnecessary start_stop_khugepaged() calls Breno Leitao
` (2 preceding siblings ...)
2026-03-10 17:57 ` [PATCH v5 3/4] mm: huge_memory: refactor enabled_store() with change_enabled() Breno Leitao
@ 2026-03-10 17:57 ` Breno Leitao
2026-03-10 18:41 ` Zi Yan
3 siblings, 1 reply; 18+ messages in thread
From: Breno Leitao @ 2026-03-10 17:57 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Zi Yan,
Baolin Wang, Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Johannes Weiner, Mike Rapoport
Cc: linux-mm, linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle), Breno Leitao
The "raising min_free_kbytes" pr_info message in
set_recommended_min_free_kbytes() and the "min_free_kbytes is not
updated to" pr_warn in calculate_min_free_kbytes() can spam the
kernel log when called repeatedly.
Switch the pr_info in set_recommended_min_free_kbytes() and the
pr_warn in calculate_min_free_kbytes() to their _ratelimited variants
to prevent the log spam for this message.
Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: Breno Leitao <leitao@debian.org>
---
mm/khugepaged.c | 4 ++--
mm/page_alloc.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 56a41c21b44c9..d44d463ccfd3e 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2671,8 +2671,8 @@ void set_recommended_min_free_kbytes(void)
if (recommended_min > min_free_kbytes) {
if (user_min_free_kbytes >= 0)
- pr_info("raising min_free_kbytes from %d to %lu to help transparent hugepage allocations\n",
- min_free_kbytes, recommended_min);
+ pr_info_ratelimited("raising min_free_kbytes from %d to %lu to help transparent hugepage allocations\n",
+ min_free_kbytes, recommended_min);
min_free_kbytes = recommended_min;
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2d4b6f1a554ed..c840c886807bf 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6553,8 +6553,8 @@ void calculate_min_free_kbytes(void)
if (new_min_free_kbytes > user_min_free_kbytes)
min_free_kbytes = clamp(new_min_free_kbytes, 128, 262144);
else
- pr_warn("min_free_kbytes is not updated to %d because user defined value %d is preferred\n",
- new_min_free_kbytes, user_min_free_kbytes);
+ pr_warn_ratelimited("min_free_kbytes is not updated to %d because user defined value %d is preferred\n",
+ new_min_free_kbytes, user_min_free_kbytes);
}
--
2.52.0
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v5 4/4] mm: ratelimit min_free_kbytes adjustment messages
2026-03-10 17:57 ` [PATCH v5 4/4] mm: ratelimit min_free_kbytes adjustment messages Breno Leitao
@ 2026-03-10 18:41 ` Zi Yan
0 siblings, 0 replies; 18+ messages in thread
From: Zi Yan @ 2026-03-10 18:41 UTC (permalink / raw)
To: Breno Leitao
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Baolin Wang,
Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
Lance Yang, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Mike Rapoport, linux-mm,
linux-kernel, usamaarif642, kas, kernel-team,
Lorenzo Stoakes (Oracle)
On 10 Mar 2026, at 13:57, Breno Leitao wrote:
> The "raising min_free_kbytes" pr_info message in
> set_recommended_min_free_kbytes() and the "min_free_kbytes is not
> updated to" pr_warn in calculate_min_free_kbytes() can spam the
> kernel log when called repeatedly.
>
> Switch the pr_info in set_recommended_min_free_kbytes() and the
> pr_warn in calculate_min_free_kbytes() to their _ratelimited variants
> to prevent the log spam for this message.
>
> Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
> mm/khugepaged.c | 4 ++--
> mm/page_alloc.c | 4 ++--
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
Makes sense.
Acked-by: Zi Yan <ziy@nvidia.com
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread