From nobody Mon Sep 28 19:34:06 2026 Received: from mta1.migadu.com (out-60.mta1.migadu.com [95.215.58.60]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC018474266 for ; Tue, 18 Aug 2026 12:49:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.60 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787057387; cv=none; b=AWj1+jVffrK9G/B0UXymGgBy7pABz3U44v+sC//oyp7jLIhTbD8i69y9mls6QUh/KT/svfmG4mJ5QfF84oc9I54ZA9alzvnHfsLWa59+s30WptcfFEVLMduBjssa5SS2WvnjLBgn6QdJn2Qn3LQ6+gys9j9GC0ssr/Dehn5mRdM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787057387; c=relaxed/simple; bh=fXiXs/GuwkDQORi9Tljqe5tR50GgCD+UJXW/sn4Xzy8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sta4kfan3R60nNoqH/EJbesSFNwftQFHmPZD/eBHeoSdvcQbudIsy44WCqAafHV4wJbdHNs+bTCeUaUbIo9Ywd+IgpipUNG2gLJW7LMlyp1jmsMlKZ5UKyCCRdhrrBmd/KJdeBlvzCl0NZdqmjDmPJcc0hcQXly0yQAdSXvMWXk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=oqs48NcR; arc=none smtp.client-ip=95.215.58.60 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="oqs48NcR" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=fXiXs/GuwkDQORi9Tljqe5tR50GgCD+UJXW/sn4Xzy8=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787057382; v=1; x=1787662182; b=oqs48NcR4i1MvXruzYG2DQcZR34+64YOKRBYo17BJPLLYmlKJvNFuDwutMnrVcPNPuEBMLFE 0gvS71LCxdhKky0CpybXuFCIK8kLZxII+GKCHHAjkBPO26EbTQEYNQI5+AW2+Me+qng9/c3qGcY 9EgCl8/vgD/nF5wIetEWo9cA= X-Envelope-To: linux-kernel@vger.kernel.org Received: from teawater-KVM-Virtual-Machine (39.156.73.13) by smtp.migadu.com with ESMTPS id c43fdcd8a3688fdf; Tue, 18 Aug 2026 12:49:42 +0000 X-Migadu-Flow: FLOW_OUT From: "Hui Zhu" To: Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Johannes Weiner , David Hildenbrand , Michal Hocko , Lorenzo Stoakes , Baolin Wang , linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: Hui Zhu Subject: [PATCH mm-unstable v3 1/2] mm/vmscan: fix missing NR_ISOLATED counter update in MGLRU reclaim path Date: Tue, 18 Aug 2026 20:48:56 +0800 Message-ID: <8488e685f584e23c164e00a761c00c1104474815.1787056208.git.zhuhui@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Hui Zhu MGLRU evict_folios() isolates folios from the LRU without updating the NR_ISOLATED_ANON/FILE counters, unlike the legacy shrink_inactive_list() path. This causes compaction's too_many_isolated() check to under-count isolated pages when MGLRU reclaim is active. Add NR_ISOLATED counter updates in evict_folios(): increment after isolate_folios() and decrement after all retry passes complete, using the existing nr_isolated which holds the original isolated count. Signed-off-by: Hui Zhu Reviewed-by: Baolin Wang Reviewed-by: Barry Song --- mm/vmscan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index c1404a59523d..98226bb021f3 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -4892,6 +4892,9 @@ static int evict_folios(unsigned long nr_to_scan, str= uct lruvec *lruvec, scanned =3D isolate_folios(nr_to_scan, lruvec, sc, swappiness, &list, &isolated, &type, &type_scanned); nr_isolated =3D isolated; + if (nr_isolated) + __mod_node_page_state(pgdat, NR_ISOLATED_ANON + type, + nr_isolated); =20 /* Scanning may have emptied the oldest gen, flush it */ if (scanned) @@ -4954,6 +4957,8 @@ static int evict_folios(unsigned long nr_to_scan, str= uct lruvec *lruvec, goto retry; } =20 + mod_node_page_state(pgdat, NR_ISOLATED_ANON + type, -nr_isolated); + if (nr_isolated > total_reclaimed) mod_lruvec_state(lruvec, PGROTATE_ANON + type, nr_isolated - total_reclaimed); --=20 2.53.0 From nobody Mon Sep 28 19:34:06 2026 Received: from mta0.migadu.com (out-46.mta0.migadu.com [91.218.175.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF5FD472783 for ; Tue, 18 Aug 2026 12:49:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787057394; cv=none; b=rNk+wua1lHQHgvgpqfLaZhQxMO/TaarWS8ojgsW5uOLQFcMn6phWvUFe9MovgoDIGfyA7iOAMExGrPQF8NdMqI/owvdF8EzfQt+qLXkZhy6YomKlHop2o7IkOX7eovNPeaZy3uatQh87zM3RMVeB+C+1SBeBR18hsP98gFWrfqs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787057394; c=relaxed/simple; bh=+ZaGSzQvA67tttFmZkgVqyG/izCzwDTO3GPvWzOf9tU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=chl4k+U1sXWSCElM3oKv/4+1JRJQbxBXPhp/p7ziGTOdihfUWa4WjkIefmKSON37KKBt+rG17mNR0oJ0YR0K1ZuwJOFr+SfKCxD3yWWbfN0DJxtZgX18lyABDmu6uRjzdPUWt3PJNU8zxXo7Cvgnm5lIlFTwdWpNCoiA4+WUlu8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=MZRAhGIA; arc=none smtp.client-ip=91.218.175.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="MZRAhGIA" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=+ZaGSzQvA67tttFmZkgVqyG/izCzwDTO3GPvWzOf9tU=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1787057390; v=1; x=1787662190; b=MZRAhGIA9plhsfxMA5xurbNG3zc0ex1U2g4d9BPNSbweFd9SE24u2738XehVtbLhh6wlf0FZ hfzR5qgztknQy5D8lstAs1HDBBp5t1EnjzWI/Ji6GHF+uuFVEwU/l3xduRQDqyG4/KwQzDmp4YQ O36Bt77UUnd49Puzpqz7qDiA= X-Envelope-To: linux-kernel@vger.kernel.org Received: from teawater-KVM-Virtual-Machine (39.156.73.13) by smtp.migadu.com with ESMTPS id 9ee484d082169ca3; Tue, 18 Aug 2026 12:49:50 +0000 X-Migadu-Flow: FLOW_OUT From: "Hui Zhu" To: Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Johannes Weiner , David Hildenbrand , Michal Hocko , Lorenzo Stoakes , Baolin Wang , linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: Hui Zhu Subject: [PATCH mm-unstable v3 2/2] mm/vmscan: apply too_many_isolated() throttling to MGLRU eviction Date: Tue, 18 Aug 2026 20:48:57 +0800 Message-ID: <4b4d4e3065e36f1b60dd69e8276cb92082f393a6.1787056208.git.zhuhui@kylinos.cn> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Hui Zhu The legacy path throttles direct reclaim in shrink_inactive_list() when too many isolated folios pile up, but MGLRU's evict_folios() isolates folios without this check, which can lead to unnecessary swapping, thrashing and OOM. With the NR_ISOLATED counters now updated in evict_folios(), extract the throttling loop from shrink_inactive_list() into throttle_is_throttled() and reuse it in evict_folios(). Since the type to isolate is unknown until isolation and isolate_folios() may fall back to the other type, check all evictable types with for_each_evictable_type() and throttle if any of them has too many isolated folios. If a fatal signal is pending, fake reclaim progress the same way the legacy path does, so the dying task exits reclaim quickly instead of being held in the throttle. Signed-off-by: Hui Zhu --- mm/vmscan.c | 71 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 98226bb021f3..6fe8824430ac 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1819,7 +1819,7 @@ bool folio_isolate_lru(struct folio *folio) * the LRU list will go small and be scanned faster than necessary, leadin= g to * unnecessary swapping, thrashing and OOM. */ -static bool too_many_isolated(struct pglist_data *pgdat, int file, +static bool too_many_isolated(struct pglist_data *pgdat, bool file, struct scan_control *sc) { unsigned long inactive, isolated; @@ -1856,6 +1856,37 @@ static bool too_many_isolated(struct pglist_data *pg= dat, int file, return too_many; } =20 +/* + * Throttle reclaim if too many isolated folios are piling up. If this mak= es + * no progress, the caller is probably looping on unevictable folios, so g= ive + * up. Returns true to tell the caller to stop reclaiming, and sets @fatal + * if the task received a fatal signal while waiting, so that the caller c= an + * bail out faster. + */ +static bool throttle_is_throttled(struct pglist_data *pgdat, bool file, + struct scan_control *sc, bool *fatal) +{ + bool stalled =3D false; + + *fatal =3D false; + while (unlikely(too_many_isolated(pgdat, file, sc))) { + if (stalled) + return true; + + /* wait a bit for the reclaimer. */ + stalled =3D true; + reclaim_throttle(pgdat, VMSCAN_THROTTLE_ISOLATED); + + /* We are about to die and free our memory. Return now. */ + if (fatal_signal_pending(current)) { + *fatal =3D true; + return true; + } + } + + return false; +} + /* * move_folios_to_lru() moves folios from private @list to appropriate LRU= list. * @@ -1992,19 +2023,14 @@ static unsigned long shrink_inactive_list(unsigned = long nr_to_scan, bool file =3D is_file_lru(lru); enum node_stat_item item; struct pglist_data *pgdat =3D lruvec_pgdat(lruvec); - bool stalled =3D false; - - while (unlikely(too_many_isolated(pgdat, file, sc))) { - if (stalled) - return 0; - - /* wait a bit for the reclaimer. */ - stalled =3D true; - reclaim_throttle(pgdat, VMSCAN_THROTTLE_ISOLATED); + bool fatal; =20 + if (throttle_is_throttled(pgdat, file, sc, &fatal)) { /* We are about to die and free our memory. Return now. */ - if (fatal_signal_pending(current)) + if (fatal) return SWAP_CLUSTER_MAX; + + return 0; } =20 lru_add_drain(); @@ -4877,12 +4903,33 @@ static int evict_folios(unsigned long nr_to_scan, s= truct lruvec *lruvec, enum node_stat_item item; struct reclaim_stat stat; struct lru_gen_mm_walk *walk; - int scanned, reclaimed; + int i, scanned, reclaimed; int isolated =3D 0, nr_isolated =3D 0, type, type_scanned; unsigned long total_reclaimed =3D 0; bool skip_retry =3D false; struct mem_cgroup *memcg =3D lruvec_memcg(lruvec); struct pglist_data *pgdat =3D lruvec_pgdat(lruvec); + bool fatal; + + /* + * The type to isolate is unknown until isolation, and + * isolate_folios() may fall back to the other type. Throttle if + * any evictable type has too many isolated folios. + */ + for_each_evictable_type(i, swappiness) { + if (throttle_is_throttled(pgdat, i, sc, &fatal)) { + /* + * We are about to die and free our memory. Like the + * legacy path, pretend some pages were reclaimed so + * reclaim unwinds quickly instead of looping back + * into the throttle. + */ + if (fatal) + sc->nr_reclaimed +=3D SWAP_CLUSTER_MAX; + + return 0; + } + } =20 lruvec_lock_irq(lruvec); =20 --=20 2.53.0