linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mm/pagewalk: honor action in pgd_entry and p4d_entry
@ 2026-04-14  5:18 Cao Ruichuang
  2026-04-14  7:57 ` Vlastimil Babka (SUSE)
  0 siblings, 1 reply; 3+ messages in thread
From: Cao Ruichuang @ 2026-04-14  5:18 UTC (permalink / raw)
  To: akpm, david, ljs, Liam.Howlett, vbabka, rppt, surenb, mhocko
  Cc: linux-mm, linux-kernel, Cao Ruichuang

walk_pud_range() and walk_pmd_range() reset walk->action to ACTION_SUBTREE and honor ACTION_CONTINUE/ACTION_AGAIN after invoking their callbacks, but walk_pgd_range() and walk_p4d_range() do not.

That leaves the top levels with inconsistent callback semantics. In particular, ptdump sets ACTION_CONTINUE from pgd_entry() and p4d_entry() for leaf entries, but the generic walker still descends into lower levels instead of skipping the subtree.

Initialize walk->action before calling pgd_entry() and p4d_entry(), and handle ACTION_CONTINUE and ACTION_AGAIN afterwards just like the lower page-table levels do. Also update the action comment to reflect that it applies to pgd_entry() and p4d_entry() as well.
---
 include/linux/pagewalk.h |  4 ++--
 mm/pagewalk.c            | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/include/linux/pagewalk.h b/include/linux/pagewalk.h
index 88e18615dd7..d3f84781792 100644
--- a/include/linux/pagewalk.h
+++ b/include/linux/pagewalk.h
@@ -94,8 +94,8 @@ struct mm_walk_ops {
 };
 
 /*
- * Action for pud_entry / pmd_entry callbacks.
- * ACTION_SUBTREE is the default
+ * Action for pgd_entry / p4d_entry / pud_entry / pmd_entry callbacks.
+ * ACTION_SUBTREE is the default.
  */
 enum page_walk_action {
 	/* Descend to next level, splitting huge pages if needed and possible */
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 4e7bcd975c5..4268e08eabb 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -261,6 +261,7 @@ static int walk_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
 
 	p4d = p4d_offset(pgd, addr);
 	do {
+again:
 		next = p4d_addr_end(addr, end);
 		if (p4d_none_or_clear_bad(p4d)) {
 			if (has_install)
@@ -272,11 +273,20 @@ static int walk_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
 			if (!has_install)
 				continue;
 		}
+
+		walk->action = ACTION_SUBTREE;
+
 		if (ops->p4d_entry) {
 			err = ops->p4d_entry(p4d, addr, next, walk);
 			if (err)
 				break;
 		}
+
+		if (walk->action == ACTION_AGAIN)
+			goto again;
+		if (walk->action == ACTION_CONTINUE)
+			continue;
+
 		if (has_handler || has_install)
 			err = walk_pud_range(p4d, addr, next, walk);
 		if (err)
@@ -302,6 +312,7 @@ static int walk_pgd_range(unsigned long addr, unsigned long end,
 	else
 		pgd = pgd_offset(walk->mm, addr);
 	do {
+again:
 		next = pgd_addr_end(addr, end);
 		if (pgd_none_or_clear_bad(pgd)) {
 			if (has_install)
@@ -313,11 +324,20 @@ static int walk_pgd_range(unsigned long addr, unsigned long end,
 			if (!has_install)
 				continue;
 		}
+
+		walk->action = ACTION_SUBTREE;
+
 		if (ops->pgd_entry) {
 			err = ops->pgd_entry(pgd, addr, next, walk);
 			if (err)
 				break;
 		}
+
+		if (walk->action == ACTION_AGAIN)
+			goto again;
+		if (walk->action == ACTION_CONTINUE)
+			continue;
+
 		if (has_handler || has_install)
 			err = walk_p4d_range(pgd, addr, next, walk);
 		if (err)

base-commit: e39f5a33eec1a4ea03358d82e861d6bb0a426b17
-- 
2.39.5 (Apple Git-154)



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

* Re: [PATCH] mm/pagewalk: honor action in pgd_entry and p4d_entry
  2026-04-14  5:18 [PATCH] mm/pagewalk: honor action in pgd_entry and p4d_entry Cao Ruichuang
@ 2026-04-14  7:57 ` Vlastimil Babka (SUSE)
  2026-04-14  8:07   ` David Hildenbrand (Arm)
  0 siblings, 1 reply; 3+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-04-14  7:57 UTC (permalink / raw)
  To: Cao Ruichuang, akpm, david, ljs, Liam.Howlett, rppt, surenb, mhocko
  Cc: linux-mm, linux-kernel

On 4/14/26 07:18, Cao Ruichuang wrote:
> walk_pud_range() and walk_pmd_range() reset walk->action to ACTION_SUBTREE and honor ACTION_CONTINUE/ACTION_AGAIN after invoking their callbacks, but walk_pgd_range() and walk_p4d_range() do not.
> 
> That leaves the top levels with inconsistent callback semantics. In particular, ptdump sets ACTION_CONTINUE from pgd_entry() and p4d_entry() for leaf entries, but the generic walker still descends into lower levels instead of skipping the subtree.
> 
> Initialize walk->action before calling pgd_entry() and p4d_entry(), and handle ACTION_CONTINUE and ACTION_AGAIN afterwards just like the lower page-table levels do. Also update the action comment to reflect that it applies to pgd_entry() and p4d_entry() as well.

Your LLM has broken line wrapping. But it's ok, we're not interested in
patches produced by LLM reviewing code, with no human oversight and
understanding. NAK.

> ---
>  include/linux/pagewalk.h |  4 ++--
>  mm/pagewalk.c            | 20 ++++++++++++++++++++
>  2 files changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/pagewalk.h b/include/linux/pagewalk.h
> index 88e18615dd7..d3f84781792 100644
> --- a/include/linux/pagewalk.h
> +++ b/include/linux/pagewalk.h
> @@ -94,8 +94,8 @@ struct mm_walk_ops {
>  };
>  
>  /*
> - * Action for pud_entry / pmd_entry callbacks.
> - * ACTION_SUBTREE is the default
> + * Action for pgd_entry / p4d_entry / pud_entry / pmd_entry callbacks.
> + * ACTION_SUBTREE is the default.
>   */
>  enum page_walk_action {
>  	/* Descend to next level, splitting huge pages if needed and possible */
> diff --git a/mm/pagewalk.c b/mm/pagewalk.c
> index 4e7bcd975c5..4268e08eabb 100644
> --- a/mm/pagewalk.c
> +++ b/mm/pagewalk.c
> @@ -261,6 +261,7 @@ static int walk_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
>  
>  	p4d = p4d_offset(pgd, addr);
>  	do {
> +again:
>  		next = p4d_addr_end(addr, end);
>  		if (p4d_none_or_clear_bad(p4d)) {
>  			if (has_install)
> @@ -272,11 +273,20 @@ static int walk_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
>  			if (!has_install)
>  				continue;
>  		}
> +
> +		walk->action = ACTION_SUBTREE;
> +
>  		if (ops->p4d_entry) {
>  			err = ops->p4d_entry(p4d, addr, next, walk);
>  			if (err)
>  				break;
>  		}
> +
> +		if (walk->action == ACTION_AGAIN)
> +			goto again;
> +		if (walk->action == ACTION_CONTINUE)
> +			continue;
> +
>  		if (has_handler || has_install)
>  			err = walk_pud_range(p4d, addr, next, walk);
>  		if (err)
> @@ -302,6 +312,7 @@ static int walk_pgd_range(unsigned long addr, unsigned long end,
>  	else
>  		pgd = pgd_offset(walk->mm, addr);
>  	do {
> +again:
>  		next = pgd_addr_end(addr, end);
>  		if (pgd_none_or_clear_bad(pgd)) {
>  			if (has_install)
> @@ -313,11 +324,20 @@ static int walk_pgd_range(unsigned long addr, unsigned long end,
>  			if (!has_install)
>  				continue;
>  		}
> +
> +		walk->action = ACTION_SUBTREE;
> +
>  		if (ops->pgd_entry) {
>  			err = ops->pgd_entry(pgd, addr, next, walk);
>  			if (err)
>  				break;
>  		}
> +
> +		if (walk->action == ACTION_AGAIN)
> +			goto again;
> +		if (walk->action == ACTION_CONTINUE)
> +			continue;
> +
>  		if (has_handler || has_install)
>  			err = walk_p4d_range(pgd, addr, next, walk);
>  		if (err)
> 
> base-commit: e39f5a33eec1a4ea03358d82e861d6bb0a426b17



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

* Re: [PATCH] mm/pagewalk: honor action in pgd_entry and p4d_entry
  2026-04-14  7:57 ` Vlastimil Babka (SUSE)
@ 2026-04-14  8:07   ` David Hildenbrand (Arm)
  0 siblings, 0 replies; 3+ messages in thread
From: David Hildenbrand (Arm) @ 2026-04-14  8:07 UTC (permalink / raw)
  To: Vlastimil Babka (SUSE),
	Cao Ruichuang, akpm, ljs, Liam.Howlett, rppt, surenb, mhocko
  Cc: linux-mm, linux-kernel

On 4/14/26 09:57, Vlastimil Babka (SUSE) wrote:
> On 4/14/26 07:18, Cao Ruichuang wrote:
>> walk_pud_range() and walk_pmd_range() reset walk->action to ACTION_SUBTREE and honor ACTION_CONTINUE/ACTION_AGAIN after invoking their callbacks, but walk_pgd_range() and walk_p4d_range() do not.
>>
>> That leaves the top levels with inconsistent callback semantics. In particular, ptdump sets ACTION_CONTINUE from pgd_entry() and p4d_entry() for leaf entries, but the generic walker still descends into lower levels instead of skipping the subtree.
>>
>> Initialize walk->action before calling pgd_entry() and p4d_entry(), and handle ACTION_CONTINUE and ACTION_AGAIN afterwards just like the lower page-table levels do. Also update the action comment to reflect that it applies to pgd_entry() and p4d_entry() as well.
> 
> Your LLM has broken line wrapping. But it's ok, we're not interested in
> patches produced by LLM reviewing code, with no human oversight and
> understanding. NAK.

Agreed. The educated reader would know that we never end up with p4d/pgd
leaves in non-hugetlb VMAs.

The ptdump code is overly cautious ;)

-- 
Cheers,

David


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

end of thread, other threads:[~2026-04-14  8:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-14  5:18 [PATCH] mm/pagewalk: honor action in pgd_entry and p4d_entry Cao Ruichuang
2026-04-14  7:57 ` Vlastimil Babka (SUSE)
2026-04-14  8:07   ` David Hildenbrand (Arm)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox