Re: [PATCH] mm: Require LRU reclaim progress before retrying direct reclaim

From: Matt Fleming

Date: Thu Apr 16 2026 - 10:57:16 EST


On Wed, Apr 15, 2026 at 06:01:54PM -0700, Shakeel Butt wrote:
> On Fri, Apr 10, 2026 at 11:15:49AM +0100, Matt Fleming wrote:
> >
> > @@ -4637,7 +4672,24 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order,
> > !__cpuset_zone_allowed(zone, gfp_mask))
> > continue;
> >
> > - available = reclaimable = zone_reclaimable_pages(zone);
> > + /*
> > + * Only count reclaimable pages from an LRU type if reclaim
> > + * actually made headway on that type in the last cycle.
> > + * This prevents the allocator from looping endlessly on
> > + * account of a large pool of pages that reclaim cannot make
> > + * progress on, e.g. anonymous pages when the only swap is
> > + * RAM-backed (zram).
> > + */
> > + reclaimable = 0;
> > + reclaimable_file = zone_reclaimable_file_pages(zone);
> > + reclaimable_anon = zone_reclaimable_anon_pages(zone);
>
> Here we are getting the current reclaimable pages.
>
> > +
> > + if (reclaim_progress_sufficient(progress->nr_file, reclaimable_file))
> > + reclaimable += reclaimable_file;
> > + if (reclaim_progress_sufficient(progress->nr_anon, reclaimable_anon))
> > + reclaimable += reclaimable_anon;
>
> And here we are comparing the current reclaimable pages with last iteration. Is
> this intentional to keep things simple?

Yep, that was the intent.

> > +
> > + available = reclaimable;
> > available += zone_page_state_snapshot(zone, NR_FREE_PAGES);
> >
>
> Another heuristic we can play with is to also pass through the vmscan scan
> count. If for couple of consecutive iterations, we continue to see low reclaim
> efficiency, go for OOM. Also maybe compare the scan count with the watermark as
> I expect we don't see much difference scan count for consecutive reclaim
> iteration, so, it is a good representative of reclaimable memory.
>
> The reclaim efficiency heuristic should handle the swap-on-zram or
> incomp-zswap-with-no-writeback. Treating scan count as proxy for reclaimable
> memory should handle the overcommitted memory.min case.

Nice. I'll take a look at this.