Re: [RFC PATCH v2 4/5] mm: mglru: run aging when pages are severely imbalanced across gens

From: Barry Song

Date: Wed Jul 29 2026 - 18:41:07 EST


On Tue, Jul 28, 2026 at 8:27 PM Zicheng Wang <wangzicheng@xxxxxxxxx> wrote:
>
> Hi Barry,
>
> > The original code is a bit odd, as it compares a single young
> > generation and a single old generation against the total, rather than
> > comparing all young generations with all old generations.
> >
> > By comparing all young generations against all old generations, we no
> > longer depend on the exact value of MIN_NR_GENS. The idea is to
> > emulate inactive_is_low().
>
> Makes sense, the inactive_is_low() framing fits.
>
> One gap: inactive_is_low()'s ratio is dynamic calculated.
> int_sqrt(10*1024) = 101 (ages only when inactive drops below ~1%),
> while patch 4/5's fixed 4 ages once old falls under 20% of young.
> It seems there will be considerable cost on big memcgs, or should
> the ratio scale with size?
>
> Looking forward to the perf data.

I don't have access to a machine with 1 TB of memory—or even
more than 20 GB—to test this. But I think your comment makes
sense. We shouldn't let a machine with a huge amount of memory
in a single lruvec age too aggressively.
So maybe something like this:

diff --git a/mm/vmscan.c b/mm/vmscan.c
index ed35c502923d..a6768b9ec8d6 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4968,6 +4968,7 @@ static bool lru_gen_imbalanced(struct lruvec
*lruvec, int type,
{
struct lru_gen_folio *lrugen = &lruvec->lrugen;
unsigned long young = 0, old = 0, seq;
+ unsigned long old_ratio, gb;

/*
* reclaim is forced to a single type in those cases, so there is
@@ -4989,7 +4990,16 @@ static bool lru_gen_imbalanced(struct lruvec
*lruvec, int type,
else
old += size;
}
- return young > old * 4;
+
+ /*
+ * Copied from the active/inactive LRU heuristic, but uses a higher
+ * old_ratio so fewer folios remain in the old generations, avoiding
+ * overly aggressive aging.
+ */
+ gb = (young + old) >> (30 - PAGE_SHIFT);
+ old_ratio = gb ? int_sqrt(10 * gb) : 1;
+ old <<= 2;
+ return young > old * old_ratio;
}

Best Regards
Barry