[RFC PATCH v5 12/14] mm/mglru: Avoid prolonged anon reclaim with swappiness=200
From: Barry Song (Xiaomi)
Date: Thu Oct 22 2026 - 18:08:03 EST
From: lyugaofei <lyugaofei@xxxxxxxxxx>
It has been observed that swappiness=200 can significantly slow down
reclaim on some machines, with some workloads running 3x slower
under MGLRU than under CLRU.
This is because swappiness=200 currently results in file_factor=0.
Give file reclaim a small factor at lower priorities, for example,
when sc->priority < DEF_PRIORITY / 2.
Signed-off-by: lyugaofei <lyugaofei@xxxxxxxxxx>
Co-developed-by: Barry Song (Xiaomi) <baohua@xxxxxxxxxx>
Signed-off-by: Barry Song (Xiaomi) <baohua@xxxxxxxxxx>
---
mm/vmscan.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 555359cc0368..81e81d69e67e 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -5056,8 +5056,8 @@ static int get_tier_idx(struct lruvec *lruvec, int type)
* We don't calculate the scan cost, MGLRU uses lazy promotion, which will
* cancel the scan budget natually.
*/
-static void lru_gen_balance_scan(struct lruvec *lruvec, int swappiness,
- unsigned long total_scan, unsigned long nr[])
+static void lru_gen_balance_scan(struct lruvec *lruvec, struct scan_control *sc,
+ int swappiness, unsigned long total_scan, unsigned long nr[])
{
struct lru_gen_folio *lrugen = &lruvec->lrugen;
u64 refault_rate[ANON_AND_FILE], anon_factor, file_factor;
@@ -5114,7 +5114,12 @@ static void lru_gen_balance_scan(struct lruvec *lruvec, int swappiness,
file_weight = nr[LRU_GEN_FILE] + nr[LRU_GEN_ANON] / size_bias;
anon_factor = (u64)swappiness * refault_rate[LRU_GEN_FILE] * anon_weight;
- file_factor = (u64)(MAX_SWAPPINESS - swappiness) * refault_rate[LRU_GEN_ANON] * file_weight;
+ if (swappiness == MAX_SWAPPINESS)
+ file_factor = sc->priority < DEF_PRIORITY / 2 ?
+ refault_rate[LRU_GEN_ANON] * file_weight : 0;
+ else
+ file_factor = (u64)(MAX_SWAPPINESS - swappiness) *
+ refault_rate[LRU_GEN_ANON] * file_weight;
/* Cross-multiply the ratio above. */
anon_scan = mul_u64_u64_div_u64(total_scan, anon_factor, anon_factor + file_factor);
@@ -5305,7 +5310,7 @@ static void lru_gen_prepare_scan(struct lruvec *lruvec, struct scan_control *sc,
total = apply_proportional_protection(memcg, sc, total);
total >>= sc->priority;
- lru_gen_balance_scan(lruvec, swappiness, total, nr_to_scan);
+ lru_gen_balance_scan(lruvec, sc, swappiness, total, nr_to_scan);
}
static bool should_abort_scan(struct lruvec *lruvec, struct scan_control *sc)
@@ -6050,7 +6055,7 @@ static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_co
return 0;
lruvec_evictable_size(lruvec, swappiness, nr_to_scan);
- lru_gen_balance_scan(lruvec, swappiness,
+ lru_gen_balance_scan(lruvec, sc, swappiness,
nr_to_reclaim - sc->nr_reclaimed, nr_to_scan);
if (!evict_folio_lists(nr_to_scan, lruvec, sc, swappiness, MAX_LRU_BATCH))
--
2.34.1