Currently, lru_gen_imbalanced() uses a fixed threshold (MAX_NR_GENS) to determine whether the young-to-old folio ratio warrants aging the preferred LRU type. This fixed threshold may not scale well with large memory systems. Borrow the adaptive ratio calculation from inactive_is_low() by scaling the threshold with the square root of the memory size in GB. Suggested-by: Zicheng Wang Signed-off-by: Barry Song (Xiaomi) --- mm/vmscan.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index d6fac5b91ac1..c0350a8b61d1 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -5105,6 +5105,7 @@ static bool lru_gen_imbalanced(struct lruvec *lruvec, unsigned long max_seq, { struct lru_gen_folio *lrugen = &lruvec->lrugen; unsigned long young = 0, old = 0, lag = 0; + unsigned long inactive_ratio, gb; DEFINE_MIN_SEQ(lruvec); /* we still have enough generations to reclaim */ @@ -5127,7 +5128,13 @@ static bool lru_gen_imbalanced(struct lruvec *lruvec, unsigned long max_seq, if (min_seq[!type] + MAX_NR_GENS == max_seq + 1) lag += lruvec_gen_size(lrugen, !type, min_seq[!type]); - return young > old * MAX_NR_GENS && (lag < MAX_LRU_BATCH || + /* + * Borrow the adaptive ratio from inactive_is_low(), and scale + * it by sqrt(MAX_NR_GENS) to make aging less aggressive + */ + gb = (young + old) >> (30 - PAGE_SHIFT); + inactive_ratio = gb ? int_sqrt(10 * gb * MAX_NR_GENS) : MAX_NR_GENS; + return young > old * inactive_ratio && (lag < MAX_LRU_BATCH || (is_extreme_swappiness(swappiness) && sc->priority > 2)); } -- 2.34.1