Re: [PATCH v2] mm: vmscan: abort proactive reclaim early when freezing for suspend
From: Michal Hocko
Date: Thu Jul 09 2026 - 08:17:25 EST
On Thu 09-07-26 07:22:31, Richard Chang wrote:
> Proactive reclaim (triggered via memory.reclaim or node sysfs)
> checks for pending signals in its outer loop in
> user_proactive_reclaim(). However, the inner reclaim
> loops—specifically scanning cgroups in shrink_many() and
> evicting/aging folios in try_to_shrink_lruvec()—can run for a long
> time before returning to the outer loop, especially on systems with
> many cgroups or large memory sizes.
>
> During system suspend, the PM freezer attempts to freeze all the tasks
> by sending signals. Because the inner loops do not check for pending
> signals, the proactive reclaim task can remain stuck in kernel space
> for seconds, failing to enter the refrigerator in a timely manner. This
> leads to suspend failures due to freeze timeouts, a behavior observed
> on Android devices.
>
> This latency issue is specific to proactive reclaim because of its
> large, user-defined reclaim targets (could be gigabytes). Since commit
> 287d5fedb377 ("mm: memcg: use larger batches for proactive reclaim"),
> proactive reclaim uses larger decaying batch sizes (starting at 1/4
> of the remaining target) to maintain throughput. This keeps the task
> in the reclaim loop with a large target for a single syscall
> invocation. In contrast, reactive reclaim (global/memcg) has small
> targets (SWAP_CLUSTER_MAX, typically 32 pages), allowing to yield or
> check signals between attempts quickly.
>
> To fix this, add a signal_pending() check to should_abort_scan() for
> proactive reclaim paths. Since should_abort_scan() is called within
> the inner scanning and eviction loops, this allows proactive reclaim to
> abort early and return to the outer loop, ensuring the task can enter
> the refrigerator and allow suspend to proceed.
>
> The check is limited to proactive reclaim (sc->proactive) to avoid
> affecting reactive reclaim paths, and wrapped in unlikely() as it
> is a slow path.
The changelog doesn't explain whether this is MGRLU specific problem as
the fix is MGRLU specific AFAICS.
Also do I get it right that freezing a task while doing the pro-active
reclaim will force EINTR early return even if no real signal was
delivered to the task?
> Signed-off-by: Richard Chang <richardycc@xxxxxxxxxx>
> ---
> v2: Update the commit message
>
> mm/vmscan.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 35c3bb15ae96..fb472e924fc7 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -4929,6 +4929,9 @@ static bool should_abort_scan(struct lruvec *lruvec, struct scan_control *sc)
> int i;
> enum zone_watermarks mark;
>
> + if (unlikely(sc->proactive && signal_pending(current)))
> + return true;
> +
> if (sc->nr_reclaimed >= max(sc->nr_to_reclaim, compact_gap(sc->order)))
> return true;
>
> --
> 2.55.0.795.g602f6c329a-goog
--
Michal Hocko
SUSE Labs