Re: [PATCH v3 01/47] mm/mglru: don't use stack pointers when walking PUD and PMD tables

From: Baoquan He

Date: Sat Oct 31 2026 - 23:18:24 EST


On 10/31/26 at 10:39am, David Hildenbrand (Arm) wrote:
> From: Josef Bacik <josef@xxxxxxxxxxxxxx>
>
> MGLRU passes stack copies of page-table entries in walk_pud_range() and
> walk_pmd_range() when walking to the next level. These copies can become
> stale when khugepaged or MADV_DONTNEED (CONFIG_PT_RECLAIM) removes a PTE
> table concurrently.
>
> This pattern dates back to commit bd74fdaea146 ("mm: multi-gen LRU:
> support page table walks"). Likely, earlier locking masked the latent
> bug. Later changes exposed it: commit 1d65b771bc08 ("mm/khugepaged:
> retract_page_tables() without mmap or vma lock") allowed concurrent
> retraction, and commit cf4a65539c13 ("memcg-v1: no need for memcg locking
> for MGLRU") dropped the walker's outer RCU protection.
>
> The fix is simple, so just fix the original commit so we don't have to
> speculate. To fix it, pass the actual PMD/PUD pointers. This restores the
> RCU-protected lookup and validation against the live PMD. Note that the PUD
> handling is required as well to handle folded page tables correctly in all
> cases.
>
> Fix generated by an LLM and sent by Josef Bacik in private.
>
> [ david: handle walk_pud_range() as well, clarify+simplify description,
> adjust Fixes: ]
>
> Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
> Reviewed-by: Rik van Riel <riel@xxxxxxxxxxx>
> Reviewed-by: Qi Zheng <qi.zheng@xxxxxxxxx>
> Reviewed-by: Dev Jain <dev.jain@xxxxxxx>
> Reviewed-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
> Reviewed-by: Kairui Song <kasong@xxxxxxxxxxx>
> Tested-by: Muhammad Usama Anjum <usama.anjum@xxxxxxx>
> Reviewed-by: Harry Yoo (Meta) <harry@xxxxxxxxxx>
> Reviewed-by: Barry Song <baohua@xxxxxxxxxx>
> Reviewed-by: Baolin Wang <baolin.wang@xxxxxxxxxxxxxxxxx>
> Reviewed-by: Pedro Falcato <pfalcato@xxxxxxx>
> Reviewed-by: Kiryl Shutsemau (Meta) <kas@xxxxxxxxxx>
> Reviewed-by: SJ Park <sj@xxxxxxxxxx>
> Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
> ---
> mm/vmscan.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)

LGTM,

Reviewed-by: Baoquan He <baoquan.he@xxxxxxxxx>

>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 9959ca158ce83..6a1af9b92349f 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -3911,7 +3911,7 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
>
> walk->mm_stats[MM_NONLEAF_FOUND]++;
>
> - if (!walk_pte_range(&val, addr, next, args))
> + if (!walk_pte_range(pmd + i, addr, next, args))
> continue;
>
> walk->mm_stats[MM_NONLEAF_ADDED]++;
> @@ -3947,7 +3947,7 @@ static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
> if (!pud_present(val) || WARN_ON_ONCE(pud_leaf(val)))
> continue;
>
> - walk_pmd_range(&val, addr, next, args);
> + walk_pmd_range(pud + i, addr, next, args);
>
> if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
> end = (addr | ~PUD_MASK) + 1;
>
> --
> 2.43.0
>