From nobody Mon Sep 28 21:52:17 2026 Received: from mta0.migadu.com (out-26.mta0.migadu.com [91.218.175.26]) (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 E1C1323BF9F for ; Mon, 17 Aug 2026 07:11:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.26 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786950702; cv=none; b=kHLpbuXQNBpksfUyU87o2iEz6vkqNIpykOfIYpVPw1gZORG+mBYHBWhq1hyG5KXOfq6FKzdVVpBry58QaV7oI3mEwCv03vzmBxNEtNnwoQPnfykxg+UlHzVyx2Dp7wZKdOa26qGos0HVrvnjoF6BHz/AV+QMLc1a/BLptDiYGTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786950702; c=relaxed/simple; bh=+56yCAHiWCEnfO07Nsz8V8P0z6H6SKj/KxqPoT0BAcE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hUSIO5Wyp4Rff9SiDntB6rHW7ZDomd40vSfRaidC4svLSb5RrsMfH8mfy4LRQVsoc0akOQOuWYn+2J5E7ITaIPmTpeJRm4kJIdYwpYGXfOppKQPwUhUZTv1THP42BrM71SrBJUMz4HkISrN6PmgZAG1s0QvfMDqyMKiPBo44pN0= 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=Nc10nVhX; arc=none smtp.client-ip=91.218.175.26 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="Nc10nVhX" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=+56yCAHiWCEnfO07Nsz8V8P0z6H6SKj/KxqPoT0BAcE=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1786950697; v=1; x=1787555497; b=Nc10nVhXaETKHyCOlbuk2OSkL0PS6bV/Y8GuhhiOjppqzkFDr2Wgtb0CVK990AfV4jfRy/wb B3dQCb2ktQ7p29b+guempao+MCZPpYzXCV1uEvS01R0jsUm/JdLot2VplhFb4a6oTDZ8YXvskih pUe29KJ0FVIxBFh0BK5T2qiQ= 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 f4e3b92ee359ac79; Mon, 17 Aug 2026 07:11:37 +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 , linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: Hui Zhu Subject: [PATCH mm-unstable v2 1/2] mm/vmscan: fix missing NR_ISOLATED counter update in MGLRU reclaim path Date: Mon, 17 Aug 2026 15:11:18 +0800 Message-ID: <9635d3c027bb8a5a416df04ea891a482beb3de9e.1786950138.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 --- mm/vmscan.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index c1404a59523d..fdc45d7d8fba 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,10 @@ static int evict_folios(unsigned long nr_to_scan, st= ruct lruvec *lruvec, goto retry; } =20 + if (nr_isolated) + 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 21:52:17 2026 Received: from mta0.migadu.com (out-37.mta0.migadu.com [91.218.175.37]) (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 864083B635A for ; Mon, 17 Aug 2026 07:11:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.37 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786950708; cv=none; b=g9HVwgZADeVi7EgwiVsDAaw1Y05eAKWOrdWyyhkNppKb4XK88l/B0wRaIPr9Cl5nZDsfS728kB98a4BtSQOMfOLE142xfGPM+OwJt1haIKzBVNKRMNLIyeIiatmHa9XgUMtCN/uk9/1BfdEL0FZLGiPze9+238W7cKK/qMkV4LA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786950708; c=relaxed/simple; bh=3OLU2rvZSB2pUOMJNXwVJjEcb+QRFbOjrMpr5xGgUiI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QgihVMOeoD37MwF5DNnBxFl37fmfT7WMisC+bTK66PK/2Df37r/mkKbkOHozv3DLWyW78M804ASPFOhU+22ZvmHfLHwld5JT6wMl4bEPTecZZmd/zBgewcz8ASdFh4tNo6JDld8tzz2qbi17FCTmvdJvtwK1k4sHIx9ST4qyjng= 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=q201gnM7; arc=none smtp.client-ip=91.218.175.37 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="q201gnM7" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=3OLU2rvZSB2pUOMJNXwVJjEcb+QRFbOjrMpr5xGgUiI=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1786950704; v=1; x=1787555504; b=q201gnM7ivwXTzucqw+KPo2+XS9CmJOPZn4ASokoJKWNUj2tdsNP8PoO8v5EVDmGIkY93uA1 S7R21KYyqTEH8ht1H/Ou8RFFt91pwzwc5zFi2mMk2E5kgQJfBgnal/3BMgRL2kKwwKrO7o0e9fU 8Z4wx7Jp5lJESoa6E0a2Jq7M= 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 e3652a2a4d77b910; Mon, 17 Aug 2026 07:11:44 +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 , linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: Hui Zhu Subject: [PATCH mm-unstable v2 2/2] mm/vmscan: apply too_many_isolated() throttling to MGLRU eviction Date: Mon, 17 Aug 2026 15:11:19 +0800 Message-ID: <858e2e0ae536bbe185267472d3c84a5684937131.1786950138.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_isolated() and reuse it in evict_folios(). The type to isolate is predicted with get_type_to_scan() since it is unknown until isolation. 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 | 67 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index fdc45d7d8fba..886a53f563ab 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 false 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_isolated(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 false; + + /* 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 false; + } + } + + return true; +} + /* * 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_isolated(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(); @@ -4883,6 +4909,25 @@ static int evict_folios(unsigned long nr_to_scan, st= ruct lruvec *lruvec, 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, so predict it for + * the throttling check. isolate_folios() may still fall back to the + * other type, which is fine for this heuristic. + */ + type =3D get_type_to_scan(lruvec, swappiness); + if (!throttle_isolated(pgdat, type, 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