[PATCH 6.1.y] mm/mglru: skip special VMAs in lru_gen_look_around()
Jakov Novak <[email protected]> Thu, 25 Jun 2026 23:27:51 +0200
| Newsgroups | dev.linux.lists.linux-kernel-mentees,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
From: Yu Zhao <[email protected]> [ Upstream commit c28ac3c7eb945fee6e20f47d576af68fdff1392a ] Special VMAs like VM_PFNMAP can contain anon pages from COW. There isn't much profit in doing lookaround on them. Besides, they can trigger the pte_special() warning in get_pte_pfn(). Skip them in lru_gen_look_around(). Link: https://lkml.kernel.org/r/[email protected] Fixes: 018ee47f1489 ("mm: multi-gen LRU: exploit locality in rmap") Signed-off-by: Yu Zhao <[email protected]> Reported-by: [email protected] Closes: https://lore.kernel.org/[email protected]/ Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> [fix conflicts with variable declarations and vma pointer usage] Signed-off-by: Jakov Novak <[email protected]> --- mm/vmscan.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 1f7a90ecc700..f6f8c18dc45f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -4622,6 +4622,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) struct lru_gen_mm_walk *walk; int young = 0; unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; + struct vm_area_struct *vma = pvmw->vma; struct folio *folio = pfn_folio(pvmw->pfn); struct mem_cgroup *memcg = folio_memcg(folio); struct pglist_data *pgdat = folio_pgdat(folio); @@ -4635,11 +4636,15 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) if (spin_is_contended(pvmw->ptl)) return; + /* exclude special VMAs containing anon pages from COW */ + if (vma->vm_flags & VM_SPECIAL) + return; + /* avoid taking the LRU lock under the PTL when possible */ walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; - start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start); - end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; + start = max(pvmw->address & PMD_MASK, vma->vm_start); + end = min(pvmw->address | ~PMD_MASK, vma->vm_end - 1) + 1; if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2) @@ -4660,7 +4665,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) { unsigned long pfn; - pfn = get_pte_pfn(pte[i], pvmw->vma, addr); + pfn = get_pte_pfn(pte[i], vma, addr); if (pfn == -1) continue; @@ -4671,7 +4676,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) if (!folio) continue; - if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) + if (!ptep_test_and_clear_young(vma, addr, pte + i)) VM_WARN_ON_ONCE(true); young++; -- 2.54.0