From nobody Tue Sep 29 06:59:45 2026 Received: from canpmsgout06.his.huawei.com (canpmsgout06.his.huawei.com [113.46.200.221]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF43140242B for ; Tue, 11 Aug 2026 07:35:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.221 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786433726; cv=none; b=GNt5VFTgJ1pwI07r2a++vtEWbxDHVneCQyAI2NxrGU8lYwrcMx5cC+R45n7+mtLIJLb6zFqy6tBeS2RGECQZTFkrFAJTVc6k2D+1KCFC9Y18Da6lBNK3S5V0PxxAygiLzxgKGhRttRIOHhX1vJ0OMsYITI96AwmqzhZOELF9eMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786433726; c=relaxed/simple; bh=1K8uaI6H1fZ/n6uMiiIDST2eQjYCe7mGk5OIb4Nxd6Y=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GUD0XEE3JPx/lc3pnBvJe8zQqVgLE1c6KgRdRKWtzDNEQgzgQgudEBtF1in/cEKoeAhr987I/qwvISqw3yIT4NB3PK7nyWP/CCS4yHiOqwDiMPjIi0FaTKR6KIciyirbf90tWe1gXgTuz/E2dELZkugjcQBPazCgJq3mqm0vXgE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=nHFcgoM8; arc=none smtp.client-ip=113.46.200.221 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="nHFcgoM8" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=uACuRpgQeAR3tJObhea0/lBl/BNLK4v2q1i2hPsZ9IU=; b=nHFcgoM8ACKqoIDyCz+qZzyccHxFtFz3X12kbeAOpeNpmCQxZLS8QJjEuhs7XQ2aHqAUinN3y 4+XXXNaz12QuodHN3RiDfe4+Ugvb+OFbFLBtIfPLMbuWBZn0q7+pfIXAHBfNrYbuGtW49fEQt/4 AaCX3cHk+aBY9eKFGaVJIs8= Received: from mail.maildlp.com (unknown [172.19.163.0]) by canpmsgout06.his.huawei.com (SkyGuard) with ESMTPS id 4hK36D5vhCzRhVQ; Tue, 11 Aug 2026 15:24:36 +0800 (CST) Received: from kwepemj100016.china.huawei.com (unknown [7.202.194.10]) by mail.maildlp.com (Postfix) with ESMTPS id 6CB4340561; Tue, 11 Aug 2026 15:35:11 +0800 (CST) Received: from huawei.com (10.50.85.135) by kwepemj100016.china.huawei.com (7.202.194.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Tue, 11 Aug 2026 15:35:10 +0800 From: Wupeng Ma To: , , , , , , , , CC: , , , , Wupeng Ma Subject: [PATCH 1/2] mm: vmscan: charge isolate overshoot against scan quota Date: Tue, 11 Aug 2026 15:08:48 +0800 Message-ID: <20260811070849.1332165-2-mawupeng1@huawei.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260811070849.1332165-1-mawupeng1@huawei.com> References: <20260811070849.1332165-1-mawupeng1@huawei.com> 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 X-ClientProxiedBy: kwepems100001.china.huawei.com (7.221.188.238) To kwepemj100016.china.huawei.com (7.202.194.10) Content-Type: text/plain; charset="utf-8" shrink_lruvec() charges the per-LRU budget nr[lru] in SWAP_CLUSTER_MAX (32) chunks, but isolate_lru_folios() may scan far more per call: a large folio can jump scan by many pages at once (a PMD-sized folio counts 512), and a zone-ineligible LRU walks the whole list without feeding scan back. The overshoot is never refunded, so shrink_lruvec() keeps charging only 32 per round and rescans the same folios. Have isolate_lru_folios() record its scanned count in sc->nr_isolate_scanned and let shrink_lruvec() subtract the overshoot from the remaining quota so the next round skips already-scanned folios. The field is reset to 0 before each shrink_list() call, as shrink_list() only reaches isolate_lru_folios() on some paths (active + skipped_deactivate, too_many_isolated stall bail out early); a stale value would otherwise be charged. The budget floor stays nr_to_scan via max() so an empty LRU (sc->nr_isolate_scanned =3D 0) still advances and cannot deadlock. Co-developed-by: Qiuhao Zhang Signed-off-by: Qiuhao Zhang Signed-off-by: Wupeng Ma --- mm/vmscan.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 56708d1d2dfd5..147e74f9732d5 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -164,6 +164,9 @@ struct scan_control { /* Incremented by the number of inactive pages that were scanned */ unsigned long nr_scanned; =20 + /* Number of pages that were scanned from isolate_lru_folios() */ + unsigned long nr_isolate_scanned; + /* Number of pages freed so far during a call to shrink_zones() */ unsigned long nr_reclaimed; =20 @@ -1673,7 +1676,6 @@ static __always_inline void update_lru_sizes(struct l= ruvec *lruvec, * @nr_to_scan: The number of eligible pages to look through on the list. * @lruvec: The LRU vector to pull pages from. * @dst: The temp list to put pages on to. - * @nr_scanned: The number of pages that were scanned. * @sc: The scan_control struct for this reclaim session * @lru: LRU list id for isolating * @@ -1681,8 +1683,7 @@ static __always_inline void update_lru_sizes(struct l= ruvec *lruvec, */ static unsigned long isolate_lru_folios(unsigned long nr_to_scan, struct lruvec *lruvec, struct list_head *dst, - unsigned long *nr_scanned, struct scan_control *sc, - enum lru_list lru) + struct scan_control *sc, enum lru_list lru) { struct list_head *src =3D &lruvec->lists[lru]; unsigned long nr_taken =3D 0; @@ -1766,7 +1767,7 @@ static unsigned long isolate_lru_folios(unsigned long= nr_to_scan, skipped +=3D nr_skipped[zid]; } } - *nr_scanned =3D total_scan; + sc->nr_isolate_scanned =3D total_scan; trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, nr_to_scan, total_scan, skipped, nr_taken, lru); update_lru_sizes(lruvec, lru, nr_zone_taken); @@ -2014,8 +2015,8 @@ static unsigned long shrink_inactive_list(unsigned lo= ng nr_to_scan, =20 lruvec_lock_irq(lruvec); =20 - nr_taken =3D isolate_lru_folios(nr_to_scan, lruvec, &folio_list, - &nr_scanned, sc, lru); + nr_taken =3D isolate_lru_folios(nr_to_scan, lruvec, &folio_list, sc, lru); + nr_scanned =3D sc->nr_isolate_scanned; =20 __mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, nr_taken); item =3D PGSCAN_KSWAPD + reclaimer_offset(sc); @@ -2071,7 +2072,6 @@ static void shrink_active_list(unsigned long nr_to_sc= an, enum lru_list lru) { unsigned long nr_taken; - unsigned long nr_scanned; vm_flags_t vm_flags; LIST_HEAD(l_hold); /* The folios which were snipped off */ LIST_HEAD(l_active); @@ -2085,12 +2085,11 @@ static void shrink_active_list(unsigned long nr_to_= scan, =20 lruvec_lock_irq(lruvec); =20 - nr_taken =3D isolate_lru_folios(nr_to_scan, lruvec, &l_hold, - &nr_scanned, sc, lru); + nr_taken =3D isolate_lru_folios(nr_to_scan, lruvec, &l_hold, sc, lru); =20 __mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, nr_taken); =20 - mod_lruvec_state(lruvec, PGREFILL, nr_scanned); + mod_lruvec_state(lruvec, PGREFILL, sc->nr_isolate_scanned); =20 lruvec_unlock_irq(lruvec); =20 @@ -5920,10 +5919,21 @@ static void shrink_lruvec(struct lruvec *lruvec, st= ruct scan_control *sc) for_each_evictable_lru(lru) { if (nr[lru]) { nr_to_scan =3D min(nr[lru], SWAP_CLUSTER_MAX); - nr[lru] -=3D nr_to_scan; =20 + sc->nr_isolate_scanned =3D 0; nr_reclaimed +=3D shrink_list(lru, nr_to_scan, lruvec, sc); + /* + * isolate_lru_folios() may scan far more + * than nr_to_scan when the LRU holds + * ineligible folios (zone-skip) or large + * folios. Charge that overshoot against the + * remaining quota (clamped by min() so it + * cannot go negative) so the next iteration + * does not rescan the same skipped folios. + */ + nr[lru] -=3D min(nr[lru], + max(nr_to_scan, sc->nr_isolate_scanned)); } } =20 --=20 2.43.0 From nobody Tue Sep 29 06:59:45 2026 Received: from canpmsgout10.his.huawei.com (canpmsgout10.his.huawei.com [113.46.200.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1A326402BAA for ; Tue, 11 Aug 2026 07:35:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.225 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786433725; cv=none; b=XZ3hXKDCm/J/RJ3hPHgL3xfE32nSiaYqnq/HiZ+NSPAUayglYsFnc6C+elX0BK380+p9vzvfqJNgUCg9zZkHbV+1oiHbS2lPs1YDcIAvW8QpwPYV84X4t0l7wL/WGJ0/68GNRE3QLGZiuprgd2EIxdnBuogcr5BUHkg54EQo6R8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786433725; c=relaxed/simple; bh=+jIIH8lX35maurfZ4ZbDOVdJjmFDGjgByjeJJ6p9GZ0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=m20LZTyOS9nv4TNdOOmuPs40fduViymp3n2dKSJvHMqcvYi+6B6GbaXvWQs4yGMfvgA2L+2mISL1av6fI9Z0uAxfYdBZcncFNHgVf3U9/qDWgoQOjKjMY3eR2eIXLtlQWJ8D2FvI9Q/+bjucZFQmL7n4iLUbKMhksRs8m+Xp8XM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=2UUf9vWl; arc=none smtp.client-ip=113.46.200.225 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="2UUf9vWl" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=jB71I2AGRR0M8wrb6cuRs3B6zPtQUdkI29IkLfGLMtQ=; b=2UUf9vWl/bGoUNYEPPy5nqC04Pecukd3EkqryHKIAYE0xdKtUK+WobrG2rw67pxGai1XKY1Av F41Ajz1o0gHwcU4mqdIyaaubIvMMEewE4MeJTHR2Y2HXA2URfNptBIhCmATRiW0XPzmgWdUxCx8 u6dlEMSRA2xb7s51XOiN8qY= Received: from mail.maildlp.com (unknown [172.19.163.127]) by canpmsgout10.his.huawei.com (SkyGuard) with ESMTPS id 4hK36C4H4kz1K96b; Tue, 11 Aug 2026 15:24:35 +0800 (CST) Received: from kwepemj100016.china.huawei.com (unknown [7.202.194.10]) by mail.maildlp.com (Postfix) with ESMTPS id F1808402AB; Tue, 11 Aug 2026 15:35:11 +0800 (CST) Received: from huawei.com (10.50.85.135) by kwepemj100016.china.huawei.com (7.202.194.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Tue, 11 Aug 2026 15:35:11 +0800 From: Wupeng Ma To: , , , , , , , , CC: , , , , Wupeng Ma Subject: [PATCH 2/2] mm: vmscan: stop scanning ineligible folios after max_nr_skipped Date: Tue, 11 Aug 2026 15:08:49 +0800 Message-ID: <20260811070849.1332165-3-mawupeng1@huawei.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260811070849.1332165-1-mawupeng1@huawei.com> References: <20260811070849.1332165-1-mawupeng1@huawei.com> 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 X-ClientProxiedBy: kwepems100001.china.huawei.com (7.221.188.238) To kwepemj100016.china.huawei.com (7.202.194.10) Content-Type: text/plain; charset="utf-8" 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_fo= lios") Signed-off-by: Wupeng Ma --- mm/vmscan.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 147e74f9732d5..ac3237a58cb29 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1704,12 +1704,20 @@ static unsigned long isolate_lru_folios(unsigned lo= ng nr_to_scan, nr_pages =3D folio_nr_pages(folio); total_scan +=3D nr_pages; =20 - /* 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)] +=3D nr_pages; - move_to =3D &folios_skipped; max_nr_skipped++; + if (max_nr_skipped >=3D SWAP_CLUSTER_MAX_SKIPPED) { + list_move(&folio->lru, &folios_skipped); + break; + } + move_to =3D &folios_skipped; goto move; } =20 --=20 2.43.0