[RFC PATCH] mm/mglru: preserve inactive placement when enabling MGLRU
From: Ridong Chen
Date: Thu Aug 13 2026 - 07:03:05 EST
From: Ridong Chen <chenridong@xxxxxxxxxx>
When the LRU is switched to MGLRU (echo y > /sys/kernel/mm/lru_gen/
enabled), fill_evictable() re-inserts every folio via
lru_gen_add_folio(..., false). With reclaiming hardcoded to false, an
inactive anonymous folio (no PG_active, not in the swapcache) takes the
"gen = MIN_NR_GENS" branch in lru_gen_folio_seq() and is seeded at
seq = max_seq - 1, which lru_gen_is_active() treats as active. Its
inactive placement is lost and NR_INACTIVE_ANON is folded into
NR_ACTIVE_ANON.
Pass reclaiming=!active so a folio from an inactive list is seeded into
an older generation. Folios from the active list carry PG_active and
hit the first branch either way, so they are unchanged.
Tested on x86_64, next-20260812, 2G VM + 1G swap, ~1.5G anon pushed onto
the inactive list before enabling MGLRU:
Active(anon) Inactive(anon)
before switch (legacy) 2952 1548792 kB
after `echo y`, unpatched 1552052 0 kB
after `echo y`, patched 15144 1536636 kB
Inactive file folios stay inactive either way (NR_INACTIVE_FILE is
preserved).
Fixes: 354ed5974429 ("mm: multi-gen LRU: kill switch")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Ridong Chen <chenridong@xxxxxxxxxx>
---
mm/vmscan.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 94fc4f25e99f..2befc8d7dd3f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -5319,7 +5319,12 @@ static bool fill_evictable(struct lruvec *lruvec)
VM_WARN_ON_ONCE_FOLIO(folio_lru_gen(folio) != -1, folio);
lruvec_del_folio(lruvec, folio);
- success = lru_gen_add_folio(lruvec, folio, false);
+ /*
+ * Keep a folio from the inactive list inactive:
+ * pass reclaiming=!active so it is not seeded as
+ * active. See lru_gen_folio_seq().
+ */
+ success = lru_gen_add_folio(lruvec, folio, !active);
VM_WARN_ON_ONCE(!success);
if (!--remaining)
--
2.34.1