Re: [PATCH resend 2/2] mm: vmscan: stop scanning ineligible folios after max_nr_skipped

From: Kunwu Chan

Date: Wed Sep 09 2026 - 06:20:49 EST


On Tue, 1 Sep 2026 16:47:06 +0800 john <love_goo@xxxxxxx> wrote:

> From: Wupeng Ma <mawupeng1@xxxxxxxxxx>
>
> When reclaiming for a lower zone, isolate_lru_folios() accounts folios
> from higher zones as skipped and, once max_nr_skipped hits
> SWAP_CLUSTER_MAX_SKIPPED, force-isolates the remaining ineligible folios
> to keep the loop from spinning on the skipped ones. Those folios are
> reclaimed even though they can never satisfy the current allocation, so
> nr_reclaimed is inflated into a false progress that keeps resetting
> no_progress_loops in should_reclaim_retry() and delays the OOM.
>
> Stop scanning once max_nr_skipped is reached instead of force-isolating
> the ineligible folios. The skipped folios are already accounted in
> total_scan, so shrink_lruvec() can charge the overshoot against its scan
> budget (see the previous commit) and will not rescan them.
>
> Fixes: 1c7b17cf0594 ("mm/vmscan: fix hard LOCKUP in function isolate_lru_folios")
> Signed-off-by: Wupeng Ma <mawupeng1@xxxxxxxxxx>
> ---
> mm/vmscan.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 823af9e86efd3..375f7cd5aa441 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -1701,12 +1701,20 @@ static unsigned long isolate_lru_folios(unsigned long nr_to_scan,
> nr_pages = folio_nr_pages(folio);
> total_scan += nr_pages;
>
> - /* Using max_nr_skipped to prevent hard LOCKUP*/
> - if (max_nr_skipped < SWAP_CLUSTER_MAX_SKIPPED &&
> - (folio_zonenum(folio) > sc->reclaim_idx)) {
> + /*
> + * Using max_nr_skipped to prevent hard LOCKUP.
> + * Once the cap is hit, stop rather than force-isolating:
> + * reclaiming ineligible folios only inflates nr_reclaimed
> + * into a false progress.
> + */
> + if (folio_zonenum(folio) > sc->reclaim_idx) {
> nr_skipped[folio_zonenum(folio)] += nr_pages;
> - move_to = &folios_skipped;
> max_nr_skipped++;
> + if (max_nr_skipped >= SWAP_CLUSTER_MAX_SKIPPED) {
> + list_move(&folio->lru, &folios_skipped);
> + break;

One question about stopping the scan once max_nr_skipped reaches
SWAP_CLUSTER_MAX_SKIPPED.

Previously, reaching this limit caused the remaining ineligible folios
to be force-isolated so that the scanner would not keep looping on skipped
folios. With this change, we break out of isolate_lru_folios() instead.

Could this cause us to stop before reaching eligible folios later in the LRU?
Is SWAP_CLUSTER_MAX_SKIPPED intended to be sufficient to determine that
continuing the scan cannot make useful reclaim progress?

Thanks,
KunWu

> + }
> + move_to = &folios_skipped;
> goto move;
> }
>
> --
> 2.53.0
>
>

Sent using hkml (https://github.com/sjp38/hackermail)