Re: [PATCH mm-unstable v4 0/2] mm/vmscan: fix NR_ISOLATED accounting and throttling for MGLRU

"Hui Zhu" <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <[email protected]>
> 
> On Thu, Aug 20, 2026 at 10:49 AM Hui Zhu <[email protected]> wrote:
> 
> > 
> > From: Hui Zhu <[email protected]>
> > 
> Hello, thanks for the update!
> 
> > 
> > The legacy reclaim path updates the NR_ISOLATED_ANON/FILE node
> >  counters around isolation and throttles direct reclaimers via
> >  too_many_isolated() when isolated folios pile up. The MGLRU eviction
> >  path does neither: evict_folios() isolates folios without touching
> >  the counters and never consults too_many_isolated().
> > 
> >  Patch 1 updates NR_ISOLATED_ANON/FILE around isolation in
> >  evict_folios(), reusing the existing nr_isolated. Without this the
> >  counters stay at zero while MGLRU reclaim is active, so compaction's
> >  too_many_isolated() cannot see the pages MGLRU has isolated.
> > 
> >  Patch 2 adds throttle_evictable_types() and calls it from
> >  evict_folios(), before the lruvec lock is taken since throttling
> >  sleeps, leaving the legacy path untouched. The MGLRU check differs
> >  from the legacy per-list one in shrink_inactive_list() because
> >  isolate_folios() picks the type to scan from the refault feedback
> >  and may fall back to the other one: it computes the set of evictable
> >  types that are not over-isolated and only sleeps when all of them
> >  are, waiting once for concurrent reclaimers exactly like the legacy
> >  path. The mask of the remaining types is passed to isolate_folios(),
> >  which restricts both its initial choice and its fallback to it, so
> >  isolation never lands on an over-isolated type and a type that is
> >  merely over-isolated never blocks the reclaim of the other one.
> >  This way the MGLRU eviction path backs off when isolated folios pile
> >  up instead of thrashing the shrinking LRU lists - the scenario the
> >  too_many_isolated() check exists for. A dying task fakes reclaim
> >  progress exactly like the legacy path so it exits reclaim quickly.
> > 
> Hmm, could too_many_isolated gets over aggressive or over passive,
> since the inactive number of MGLRU is just a compatiblity shim and
> does not have the same meaning of classical LRU? Especially when you
> run out of swap space or hit a memcg's swap limit, the anon inactive
> number becomes a jumpy random number. Proactive aging also makes the
> inactive number become huge for MGLRU. I still think even a "/
> MIN_NR_GENS" is better than using inactive value, MGLRU used to use
> that as the aging trigger like this:
> 
> if (young * MIN_NR_GENS > total)
>  return true;
> if (old * (MIN_NR_GENS + 2) < total)
>  return true;
> 

Agreed. The next version drops the inactive-based threshold and
instead compares the isolated count against the total evictable pages
of the type divided by MIN_NR_GENS, and makes the check per lruvec,
where the MGLRU isolation happens.

> > 
> > Testing
> >  =======
> > 
> >  Test on 8G RAM qemu.
> >  The reproducer confines stress-ng workers in a 192M memcg and swaps
> >  through dm-delay (300ms write latency) so pageout is slow and isolated
> >  folios pile up; the workload is intentionally extreme. nr_isolated_*
> >  is sampled every 50ms against the per-type too_many_isolated
> >  threshold (inactive/8), and throttle events are counted via the
> >  mm_vmscan_throttled tracepoint.
> >  The test scripts and test log are in [1].
> > 
> >  Test 1, reclaim throttling, parallel direct reclaim in the memcg:
> > 
> >  before after
> >  throttle events (ISOLATED) 0 0
> >  - from kswapd 0 0
> >  nr_isolated_anon peak 0 3166
> >  nr_isolated_file peak 0 174
> >  - samples above the
> >  too_many_isolated threshold 0/1088 89/1077
> >  pgscan_direct 1540044096 858332151
> >  pswpout 6299497 725819
> > 
> The throttling avoids premature OOM and over scan when there are too
> many reclaimers, it is not for IO balancing. Because writeback folios
> are not isolated, they are putback to LRU waiting to be rotated, not
> isolated. So reclaimers never wait on the device however slow the
> device is (except cgroup V1 have some special quirks I think we should
> ignore), it's mostly CPU bound. I think the mechanism might be a bit
> outdated, even for classical LRU.
> 
> The result just shows that swap became less aggressive when under
> pressure, which is somewhat counter-intuitive. Overly aggressive
> throttling will unnecessarily slows performance if anon pages are
> actually cold or should be evicted. These results reflect a reclaim
> behavior change, not a performance improvement. And I think we
> shouldn't rely on throttling for balancing, those are two different
> things. Heat or I/O cost-based methods are better.

Right. This script is only meant to show that the isolation accounting
and the throttling kick in; it was not intended as a performance
evaluation. As you pointed out, it also sampled the old node-level
inactive-based threshold, which no longer matches the new check. Will
provide a new test aimed at the premature OOM / overscanning scenario.

> 
> For example the test you posted, it just stress-ng which only spawns
> anon memory IIUC, so when you reclaim file, your code segments got
> reclaimed and hence the process stall and has to wait for code
> segments IO, which I think it will only slowdown the actual
> performance?
>

Yes, will fix that in the new test as well.

Best,
Hui
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.