Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Chang <richardycc@google.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	Kairui Song <kasong@tencent.com>,  Qi Zheng <qi.zheng@linux.dev>,
	Shakeel Butt <shakeel.butt@linux.dev>,
	 Barry Song <baohua@kernel.org>,
	Axel Rasmussen <axelrasmussen@google.com>,
	 Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
	 Johannes Weiner <hannes@cmpxchg.org>,
	David Hildenbrand <david@kernel.org>,
	Michal Hocko <mhocko@kernel.org>,
	 Lorenzo Stoakes <ljs@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>,
	"T . J . Mercier" <tjmercier@google.com>,
	 Martin Liu <liumartin@google.com>,
	Minchan Kim <minchan@kernel.org>,
	 Oleg Nesterov <oleg@redhat.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	 Richard Chang <richardycc@google.com>,
	Michal Hocko <mhocko@suse.com>
Subject: [PATCH v3] mm: vmscan: abort proactive reclaim early when freezing for suspend
Date: Fri, 17 Jul 2026 18:12:52 +0000	[thread overview]
Message-ID: <20260717181252.2277818-1-richardycc@google.com> (raw)
In-Reply-To: <CALC_0q8ntqjCwC6CBN_0h_z9-_+pDp8-pqQgZ39O2s8ke==9cQ@mail.gmail.com>

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 tasks by
sending fake signals (setting TIF_SIGPENDING). 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 inner reclaim loop for extended periods. In contrast, reactive
reclaim (global/memcg) uses small targets (SWAP_CLUSTER_MAX, typically
32 pages), allowing it to return to the outer loop and check signals
frequently.

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 in user_proactive_reclaim().

Additionally, return -ERESTARTSYS instead of -EINTR in
user_proactive_reclaim(). When interrupted by system suspend, returning
-ERESTARTSYS allows the task to enter the refrigerator and automatically
restart the syscall upon resume, making the freezer transparent to
userspace. If interrupted by an unhandled real signal (e.g. SIGINT),
the kernel signal layer automatically converts -ERESTARTSYS to -EINTR.

This fix specifically targets Multi-Gen LRU (MGLRU). Classic LRU's scan
targets per iteration are strictly bounded by get_scan_count(), which
ensures it returns to the outer loop more frequently.

The check in should_abort_scan() is limited to proactive reclaim
(sc->proactive) to avoid inadvertently affecting reactive reclaim paths,
and is wrapped in unlikely() as it is a slow path.

Suggested-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Richard Chang <richardycc@google.com>
---
v2: Update the commit message
v3: Return -ERESTARTSYS instead of -EINTR in user_proactive_reclaim

 mm/vmscan.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 35c3bb15ae96..0fda811fcb05 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;
 
@@ -7909,8 +7912,14 @@ int user_proactive_reclaim(char *buf,
 		unsigned long batch_size = (nr_to_reclaim - nr_reclaimed) / 4;
 		unsigned long reclaimed;
 
+		/*
+		 * Return -ERESTARTSYS to allow the freezer to interrupt the
+		 * task. The syscall will be transparently restarted upon
+		 * resume. Real signals (e.g. SIGINT) will be automatically
+		 * converted to -EINTR by the signal layer.
+		 */
 		if (signal_pending(current))
-			return -EINTR;
+			return -ERESTARTSYS;
 
 		/*
 		 * This is the final attempt, drain percpu lru caches in the
-- 
2.55.0.229.g6434b31f56-goog



       reply	other threads:[~2026-07-17 18:13 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CALC_0q8ntqjCwC6CBN_0h_z9-_+pDp8-pqQgZ39O2s8ke==9cQ@mail.gmail.com>
2026-07-17 18:12 ` Richard Chang [this message]
2026-07-17 18:47   ` [PATCH v3] mm: vmscan: abort proactive reclaim early when freezing for suspend Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260717181252.2277818-1-richardycc@google.com \
    --to=richardycc@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=david@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=kasong@tencent.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=liumartin@google.com \
    --cc=ljs@kernel.org \
    --cc=mhocko@kernel.org \
    --cc=mhocko@suse.com \
    --cc=minchan@kernel.org \
    --cc=oleg@redhat.com \
    --cc=qi.zheng@linux.dev \
    --cc=shakeel.butt@linux.dev \
    --cc=surenb@google.com \
    --cc=tjmercier@google.com \
    --cc=weixugc@google.com \
    --cc=yuanchu@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox