[PATCH 2/2] mm: huge_memory: refactor defrag_show() to use defrag_flags[]

Breno Leitao posted 2 patches 2 weeks ago
[PATCH 2/2] mm: huge_memory: refactor defrag_show() to use defrag_flags[]
Posted by Breno Leitao 2 weeks ago
Replace the hardcoded if/else chain of test_bit() calls and string
literals in defrag_show() with a loop over defrag_flags[] and
defrag_mode_strings[] arrays introduced in the previous commit.

This makes defrag_show() consistent with defrag_store() and eliminates
the duplicated mode name strings.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
 mm/huge_memory.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 4843e2154038f..eaa6623fa49e2 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -447,24 +447,30 @@ static const enum transparent_hugepage_flag defrag_flags[] = {
 static ssize_t defrag_show(struct kobject *kobj,
 			   struct kobj_attribute *attr, char *buf)
 {
-	const char *output;
+	int active = DEFRAG_NEVER;
+	int len = 0;
+	int i;
 
-	if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG,
-		     &transparent_hugepage_flags))
-		output = "[always] defer defer+madvise madvise never";
-	else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG,
-			  &transparent_hugepage_flags))
-		output = "always [defer] defer+madvise madvise never";
-	else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG,
-			  &transparent_hugepage_flags))
-		output = "always defer [defer+madvise] madvise never";
-	else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG,
-			  &transparent_hugepage_flags))
-		output = "always defer defer+madvise [madvise] never";
-	else
-		output = "always defer defer+madvise madvise [never]";
+	for (i = 0; i < ARRAY_SIZE(defrag_flags); i++) {
+		if (test_bit(defrag_flags[i], &transparent_hugepage_flags)) {
+			active = i;
+			break;
+		}
+	}
 
-	return sysfs_emit(buf, "%s\n", output);
+	for (i = 0; i < ARRAY_SIZE(defrag_mode_strings); i++) {
+		if (i == active)
+			len += sysfs_emit_at(buf, len, "[%s] ",
+					     defrag_mode_strings[i]);
+		else
+			len += sysfs_emit_at(buf, len, "%s ",
+					     defrag_mode_strings[i]);
+	}
+
+	/* Replace trailing space with newline */
+	buf[len - 1] = '\n';
+
+	return len;
 }
 
 static ssize_t defrag_store(struct kobject *kobj,

-- 
2.52.0
Re: [PATCH 2/2] mm: huge_memory: refactor defrag_show() to use defrag_flags[]
Posted by Barry Song 21 hours ago
On Sat, Mar 21, 2026 at 12:06 AM Breno Leitao <leitao@debian.org> wrote:
>
> Replace the hardcoded if/else chain of test_bit() calls and string
> literals in defrag_show() with a loop over defrag_flags[] and
> defrag_mode_strings[] arrays introduced in the previous commit.
>
> This makes defrag_show() consistent with defrag_store() and eliminates
> the duplicated mode name strings.
>
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
>  mm/huge_memory.c | 38 ++++++++++++++++++++++----------------
>  1 file changed, 22 insertions(+), 16 deletions(-)
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 4843e2154038f..eaa6623fa49e2 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -447,24 +447,30 @@ static const enum transparent_hugepage_flag defrag_flags[] = {
>  static ssize_t defrag_show(struct kobject *kobj,
>                            struct kobj_attribute *attr, char *buf)
>  {
> -       const char *output;
> +       int active = DEFRAG_NEVER;
> +       int len = 0;
> +       int i;
>
> -       if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG,
> -                    &transparent_hugepage_flags))
> -               output = "[always] defer defer+madvise madvise never";
> -       else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG,
> -                         &transparent_hugepage_flags))
> -               output = "always [defer] defer+madvise madvise never";
> -       else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG,
> -                         &transparent_hugepage_flags))
> -               output = "always defer [defer+madvise] madvise never";
> -       else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG,
> -                         &transparent_hugepage_flags))
> -               output = "always defer defer+madvise [madvise] never";
> -       else
> -               output = "always defer defer+madvise madvise [never]";
> +       for (i = 0; i < ARRAY_SIZE(defrag_flags); i++) {
> +               if (test_bit(defrag_flags[i], &transparent_hugepage_flags)) {
> +                       active = i;
> +                       break;
> +               }
> +       }
>
> -       return sysfs_emit(buf, "%s\n", output);
> +       for (i = 0; i < ARRAY_SIZE(defrag_mode_strings); i++) {
> +               if (i == active)
> +                       len += sysfs_emit_at(buf, len, "[%s] ",
> +                                            defrag_mode_strings[i]);
> +               else
> +                       len += sysfs_emit_at(buf, len, "%s ",
> +                                            defrag_mode_strings[i]);
> +       }
> +
> +       /* Replace trailing space with newline */
> +       buf[len - 1] = '\n';
> +

Interesting. We used to use sysfs_emit(buf, "%s\n", output),
which appends a newline automatically. Now you’re replacing
the final ' ' with '\n'.

LGTM,
Reviewed-by: Barry Song <baohua@kernel.org>
Re: [PATCH 2/2] mm: huge_memory: refactor defrag_show() to use defrag_flags[]
Posted by Lance Yang 23 hours ago

On 2026/3/21 00:05, Breno Leitao wrote:
> Replace the hardcoded if/else chain of test_bit() calls and string
> literals in defrag_show() with a loop over defrag_flags[] and
> defrag_mode_strings[] arrays introduced in the previous commit.
> 
> This makes defrag_show() consistent with defrag_store() and eliminates
> the duplicated mode name strings.
> 
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---

LGTM.

Tested-by: Lance Yang <lance.yang@linux.dev>

And also,

Reviewed-by: Lance Yang <lance.yang@linux.dev>
Re: [PATCH 2/2] mm: huge_memory: refactor defrag_show() to use defrag_flags[]
Posted by David Hildenbrand (Arm) 1 day, 20 hours ago
On 3/20/26 17:05, Breno Leitao wrote:
> Replace the hardcoded if/else chain of test_bit() calls and string
> literals in defrag_show() with a loop over defrag_flags[] and
> defrag_mode_strings[] arrays introduced in the previous commit.
> 
> This makes defrag_show() consistent with defrag_store() and eliminates
> the duplicated mode name strings.
> 
> Signed-off-by: Breno Leitao <leitao@debian.org>
> ---
>  mm/huge_memory.c | 38 ++++++++++++++++++++++----------------
>  1 file changed, 22 insertions(+), 16 deletions(-)
> 
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 4843e2154038f..eaa6623fa49e2 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -447,24 +447,30 @@ static const enum transparent_hugepage_flag defrag_flags[] = {
>  static ssize_t defrag_show(struct kobject *kobj,
>  			   struct kobj_attribute *attr, char *buf)
>  {
> -	const char *output;
> +	int active = DEFRAG_NEVER;
> +	int len = 0;
> +	int i;
>  
> -	if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG,
> -		     &transparent_hugepage_flags))
> -		output = "[always] defer defer+madvise madvise never";
> -	else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG,
> -			  &transparent_hugepage_flags))
> -		output = "always [defer] defer+madvise madvise never";
> -	else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG,
> -			  &transparent_hugepage_flags))
> -		output = "always defer [defer+madvise] madvise never";
> -	else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG,
> -			  &transparent_hugepage_flags))
> -		output = "always defer defer+madvise [madvise] never";
> -	else
> -		output = "always defer defer+madvise madvise [never]";
> +	for (i = 0; i < ARRAY_SIZE(defrag_flags); i++) {
> +		if (test_bit(defrag_flags[i], &transparent_hugepage_flags)) {
> +			active = i;
> +			break;
> +		}
> +	}
>  
> -	return sysfs_emit(buf, "%s\n", output);
> +	for (i = 0; i < ARRAY_SIZE(defrag_mode_strings); i++) {
> +		if (i == active)
> +			len += sysfs_emit_at(buf, len, "[%s] ",
> +					     defrag_mode_strings[i]);
> +		else
> +			len += sysfs_emit_at(buf, len, "%s ",
> +					     defrag_mode_strings[i]);
> +	}
> +
> +	/* Replace trailing space with newline */
> +	buf[len - 1] = '\n';
> +
> +	return len;

The old code was certainly way easier to get. But this one here looks
good to me.

Acked-by: David Hildenbrand (Arm) <david@kernel.org>

-- 
Cheers,

David