[PATCH v2 10/10] mm/madvise: share cold and pageout walk setup
From: Gregory Price (Meta)
Date: Wed Oct 14 2026 - 14:33:16 EST
madvise_cold() and madvise_pageout() each open-code the same mmu_gather
and page-walk sequence, differing only in the pageout flag they pass to
the walk.
Move that sequence into madvise_lru_vma_range(), which takes the flag.
The walk now gathers into madv_behavior->tlb instead of an mmu_gather
on each caller's stack.
madvise_init_tlb() and madvise_finish_tlb() leave that mmu_gather
untouched for both behaviors, since neither batches TLB flushes
across VMAs.
No functional change intended.
Signed-off-by: Gregory Price (Meta) <gourry@xxxxxxxxxx>
---
mm/madvise.c | 37 +++++++++----------------------------
1 file changed, 9 insertions(+), 28 deletions(-)
diff --git a/mm/madvise.c b/mm/madvise.c
index acfe5b945eea..db4f498840eb 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -656,21 +656,23 @@ static const struct mm_walk_ops cold_walk_ops = {
.walk_lock = PGWALK_RDLOCK,
};
-static void madvise_cold_page_range(struct mmu_gather *tlb,
- struct madvise_behavior *madv_behavior)
-
+static void madvise_lru_vma_range(struct madvise_behavior *madv_behavior,
+ bool pageout)
{
struct vm_area_struct *vma = madv_behavior->vma;
struct madvise_behavior_range *range = &madv_behavior->range;
+ struct mmu_gather *tlb = madv_behavior->tlb;
struct madvise_walk_private walk_private = {
- .pageout = false,
+ .pageout = pageout,
.tlb = tlb,
};
+ tlb_gather_mmu(tlb, madv_behavior->mm);
tlb_start_vma(tlb, vma);
walk_page_range_vma(vma, range->start, range->end, &cold_walk_ops,
- &walk_private);
+ &walk_private);
tlb_end_vma(tlb, vma);
+ tlb_finish_mmu(tlb);
}
static inline bool can_madv_lru_vma(struct vm_area_struct *vma)
@@ -681,37 +683,18 @@ static inline bool can_madv_lru_vma(struct vm_area_struct *vma)
static long madvise_cold(struct madvise_behavior *madv_behavior)
{
struct vm_area_struct *vma = madv_behavior->vma;
- struct mmu_gather tlb;
if (!can_madv_lru_vma(vma))
return -EINVAL;
lru_add_drain();
- tlb_gather_mmu(&tlb, madv_behavior->mm);
- madvise_cold_page_range(&tlb, madv_behavior);
- tlb_finish_mmu(&tlb);
+ madvise_lru_vma_range(madv_behavior, false);
return 0;
}
-static void madvise_pageout_page_range(struct mmu_gather *tlb,
- struct vm_area_struct *vma,
- struct madvise_behavior_range *range)
-{
- struct madvise_walk_private walk_private = {
- .pageout = true,
- .tlb = tlb,
- };
-
- tlb_start_vma(tlb, vma);
- walk_page_range_vma(vma, range->start, range->end, &cold_walk_ops,
- &walk_private);
- tlb_end_vma(tlb, vma);
-}
-
static long madvise_pageout(struct madvise_behavior *madv_behavior)
{
- struct mmu_gather tlb;
struct vm_area_struct *vma = madv_behavior->vma;
if (!can_madv_lru_vma(vma))
@@ -728,9 +711,7 @@ static long madvise_pageout(struct madvise_behavior *madv_behavior)
return 0;
lru_add_drain();
- tlb_gather_mmu(&tlb, madv_behavior->mm);
- madvise_pageout_page_range(&tlb, vma, &madv_behavior->range);
- tlb_finish_mmu(&tlb);
+ madvise_lru_vma_range(madv_behavior, true);
return 0;
}
--
2.56.0