[PATCH RFC 11/32] mm/smap: report workingset folios as referenced

From: Kairui Song via B4 Relay

Date: Fri May 01 2026 - 17:07:50 EST


From: Kairui Song <kasong@xxxxxxxxxxx>

For MGLRU, switch smap to use the folio refs count API so smap will
report all folio with referenced count >= 1 as "Referenced". Current
smap checking PG_referenced is causing folios to flick between
referenced and not-reference status, because for both MGLRU and
active/inactive LRU, PG_referenced may got cleared on second access.
(Increase of LRU referenced times count for MGLRU, and movig to active
list active/inactive all clears that bit).

After this, we will have a more reliable and useful reading for MGLRU.

Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx>
---
fs/proc/task_mmu.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 751b9ba160fb..617f457c75bb 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -913,6 +913,22 @@ static void smaps_page_accumulate(struct mem_size_stats *mss,
}
}

+static bool smap_check_folio_referenced(struct folio *folio)
+{
+ if (lru_gen_enabled())
+ return folio_is_referenced(folio);
+ else
+ return folio_is_referenced_by_bit(folio);
+}
+
+static void smap_clear_folio_referenced(struct folio *folio)
+{
+ if (lru_gen_enabled())
+ folio_set_lru_refs(folio, 0);
+ else
+ folio_clear_referenced_by_bit(folio);
+}
+
static void smaps_account(struct mem_size_stats *mss, struct page *page,
bool compound, bool young, bool dirty, bool locked,
bool present)
@@ -939,7 +955,7 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,

mss->resident += size;
/* Accumulate the size in pages that have been accessed. */
- if (young || folio_test_young(folio) || folio_test_referenced(folio))
+ if (young || folio_test_young(folio) || smap_check_folio_referenced(folio))
mss->referenced += size;

/*
@@ -1701,7 +1717,7 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
/* Clear accessed and referenced bits. */
pmdp_test_and_clear_young(vma, addr, pmd);
folio_test_clear_young(folio);
- folio_clear_referenced(folio);
+ smap_clear_folio_referenced(folio);
out:
spin_unlock(ptl);
return 0;
@@ -1730,7 +1746,7 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
/* Clear accessed and referenced bits. */
ptep_test_and_clear_young(vma, addr, pte);
folio_test_clear_young(folio);
- folio_clear_referenced(folio);
+ smap_clear_folio_referenced(folio);
}
pte_unmap_unlock(pte - 1, ptl);
cond_resched();

--
2.54.0