From nobody Fri Sep 25 23:12:14 2026 Received: from outbound.st.icloud.com (st-2005h-snip4-10.eps.apple.com [57.103.79.42]) (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 992CC375F7B for ; Sun, 20 Sep 2026 14:25:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=57.103.79.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914332; cv=none; b=B8VrPVKCqfiuN1iiXkLPD7FgFViQGY1BOkSPFLu41ySBHpWQaKfEZ7216C3V/jqtA339Pn7ATr8E+b6RiBIASsLj+q6eb07G2Y1Ore4t680sL2l3ZkcsRakAfnQOe9U+XDTf/YnVlIB95gqLgOVUD7W8tsMA+Zk6zr8EDqGLqkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914332; c=relaxed/simple; bh=X1kG1tLczdpxshFwa4rihpmOvqJW54t/bXWnOoitkBg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Va6/K946wq8WWFQ/VvT5RekUtoJvEF9Jri4mCb1ZMy7/qXXCGsqPfWGROuDYS5lgrAlgcmkks22vJBvEjT6DcnHdmc3X5h6PBmc8ryNzAevW+BmoZ88eXV/wT4zTi3XN/y6sEO9R3I2mQ7e9K4TmUXKPWh854PwSI5LLeskc5zk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com; spf=pass smtp.mailfrom=icloud.com; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b=CC6rXqpY; arc=none smtp.client-ip=57.103.79.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=icloud.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b="CC6rXqpY" Received: from outbound.st.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPS id E553118005AD; Sun, 20 Sep 2026 14:25:26 +0000 (UTC) X-ICL-RepId: 01a0bf35-2754-75ac-958d-7cef7b974086 X-ICL-Out-Info: HUtFAUMEWwJACUgBTUQeDx5WFlZNRAJCTQhKB0MGWQReCEsEQwFbEhVdRUkERxtXAlQXXQZSEnIZWhRcGFNFUR9UWFUJCgJRHFYNV0NUBF9QSxsOXABLWhVVFw4CQh9QH0wWV0NEHxwZWhRcGFNFUR9UWEMZRVZpQQtPHV0ZWxxCZFhXCQoCURxWDVdDVARfUFQRV1ALWQJCD0gKXwdGRB1KG1IDGhlXFlgbRwJFRkRBFEkeCFRbBhQOSVAPAF0DME0dXQ5SBUZeWhdeUxcfSwBcRVoOWwRHFA== Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com; s=1a1hai; t=1789914330; x=1792506330; bh=itZXbhu1geEQDhiB21pBCZPn2boqK56cKpNzLhHjS5k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:x-icloud-hme; b=CC6rXqpYdJt2iWT+YOqGeKKa1bwsdtIgiMTKa+hKVReinjnwzVLGPYPw9nk3gsijeB9VM/xG0k9vf8PjXkUzOlHTqJJB/s0upcXlVKO+3eK1++8TuHtN1/NVm4drrKGvsplxm4+MrZaHt0WK4Yh8DTbl1WlwYnzmgge3SErkt7LiPIv/5CAXQkVfX3ASoELz6AjGMNapNgnJnyAtzzJNHzWPguh+xKBGodDIbu/3j23+jY/VWAUgo7TyirGwyxOfsRQ5wAAobyVcQ0FfsSlWhki8QfN5LVadMPxQb58joDLsgzc5Y0hZjzwA5RzFOH1QTITPHPbUvPb4LTldnKMf2w== Received: from [127.0.0.1] (unknown [17.156.216.30]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPSA id 7136F1800BE4; Sun, 20 Sep 2026 14:25:20 +0000 (UTC) From: Zhang Peng Date: Sun, 20 Sep 2026 22:24:14 +0800 Subject: [PATCH 1/4] mm/vmscan: introduce folio_activate_locked() helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260920-vmscan-refactor-v1-1-ec04d71cb761@tencent.com> References: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> In-Reply-To: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> To: Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Baoquan He , Baolin Wang , Johannes Weiner , David Hildenbrand , Michal Hocko , Lorenzo Stoakes Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Zhang Peng X-Mailer: b4 0.16.0 X-Authority-Info-Out: v=2.4 cv=fLc0HJae c=1 sm=1 tr=0 ts=6aafecd8 cx=c_apl:c_pps:t_out a=oyWFxbOnq+dmhQrAPgaJYA==:117 a=oyWFxbOnq+dmhQrAPgaJYA==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=x7bEGLp0ZPQA:10 a=YE32fvk_ji8A:10 a=VkNPw1HP01LnGYTKEx00:22 a=GvQkQWPkAAAA:8 a=VwQbUJbxAAAA:8 a=SVDCxekAgo2Xo8Fb88MA:9 a=QEXdDO2ut3YA:10 a=J82S1U87d15UFHHUFZS8:22 a=J6hPbylVjWXjVQVODqME:22 X-Proofpoint-ORIG-GUID: tYUsyATkRx1G_HLt-XrwRX7bTfu0HAgP X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTIwMDIxMCBTYWx0ZWRfX5wHKd7rfIJND QHzvqKnxnnhc8FS5rmfpafKEsAyMErKxYdeSRU2Z43pIXIDvF6T2Z4GGgQgC0un1oM2wp7HbbO6 S3NVgma1rQaUanjHfk67Z/5pOOcuE3hwt45zMYjyAZNDmGWJxo7AfYerRlH18eS0dMuJeYBGTGH 7v9OeLHquz5sJH7WB0sLKpFbb5Au0+0jvL3w5S2COXCFVJcMp9swn4ASc4RNN20rHm3fhrn+SBd i+2q09mAIiQJDoJBLrDNTU2nPuN0p73r8kccYytZGRcu0couLLhtyK7BYzSmeUmSJ81caRdzpdu 8g9jxSUrXiYvz5jt0CyWWE+vzPvCggCdNCmq9JFZmbC31Sa3Vn3YE9FAl0pXHE= X-Proofpoint-GUID: tYUsyATkRx1G_HLt-XrwRX7bTfu0HAgP X-JNJ: AAAAAAABWCOK1qoNcNK+506RHFFGeBNptfW73pDup1dpgJCCKC70b7XS6Zo0GCq8tojvcUlwX4gMXZQzcBdQQQC8infduJkkFUXAUbY7SviKI/S2i6LagEHi2qLfbXrrBq9uUOmINdOcO7sSKE3iS193tXpRX8A558VDXxqmUb9jYiW2O8Y/WAj1bBClaqLW6zhucz1qtwyQxSJOC2eNYmdBhxn3nhPgqZP2LPbIKuk+lIFa09yQBdthIgIo5UVMnBvgKOEs01vmY8sIifjYqWiNBnRI4qspQ9ePHP6hk89LX/sMvnqo+wYZ6RGrGjk1Ws4gWkiiflRbSBFwkLfNnuHj6q5x2wLJGeM0KI3aBOJ79Qc70FX072Mb8qgvg4Tu4K2NDCL+uVwZOydbi6qgeoQhxApNyVjGU3msAvAJoR/eFeu8V30onPIdYm1LbvEjz5EIpM2d4JuOacbC1or5kMHX8sE6cGnjw2U50oXmfAGuyEv1a+1uiUdet+Zm8Ow1wV/wVervgOvxlPhSsgrWUDoqsHrabMPUNhprRrJLwx+YMLHTDodjzWY80YK9t16C8SSg6amMSV7Oi5vdUI0gd0htbqRD0RsBkmrwB7sfBjTsz7U/qR4BdlC9qeFusz2QR7APcFY29GomXLLNsWR3DXIm6pISA6dubTauFIjsTPx7M1t0UPtA54HkzRkrjLNoeOFSNdBy1kBTroUU2Wubn7Emddt5zpSU20ewKYofgHJ5inwQrQN8yJjv0lx4sbzkgkcO1l7Lc9aeZX0kHgrG1u17D98yeA5ZR0q9OpXX+bGSID3KzheW67GF2wTzHgKA+ZmCz3mArHVJTZvY2ESNS1F2LqVzDT7Ui4qciXX1A87fnuvNhEveFPb1CyL5QOfnhoHWDktwISYgJAdgvkKAAFu3rDoNIiWTyW/VaQ6e+MphPSEsEjlSNeYZgGhR From: Zhang Peng The activate_locked label in shrink_folio_list() reclaims swap cache when needed, marks the folio active, and updates activation statistics. Extract this block into folio_activate_locked() so it can be reused. Replace the active-folio BUG with a warning so a bad caller is reported without taking down the system. Otherwise, there is no functional change. Reviewed-by: Barry Song Signed-off-by: Zhang Peng Suggested-by: Kairui Song --- mm/vmscan.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index e200ce3eb056..c6beca88079a 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1155,6 +1155,28 @@ static bool may_enter_fs(struct folio *folio, gfp_t = gfp_mask) return false; } =20 +/* Activate an isolated, locked folio and account the activation. */ +static void folio_activate_locked(struct folio *folio, + struct reclaim_stat *stat) +{ + unsigned int nr_pages =3D folio_nr_pages(folio); + + VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); + VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio), folio); + + /* Not a candidate for swapping, so reclaim swap space. */ + if (folio_test_swapcache(folio) && + (mem_cgroup_swap_full(folio) || folio_test_mlocked(folio))) + folio_free_swap(folio); + if (!folio_test_mlocked(folio)) { + int type =3D folio_is_file_lru(folio); + + folio_set_active(folio); + stat->nr_activate[type] +=3D nr_pages; + count_memcg_folio_events(folio, PGACTIVATE, nr_pages); + } +} + /* * shrink_folio_list() returns the number of reclaimed pages */ @@ -1623,24 +1645,12 @@ static unsigned int shrink_folio_list(struct list_h= ead *folio_list, activate_locked_split: /* * The tail pages that are failed to add into swap cache - * reach here. Fixup nr_scanned and nr_pages. + * reach here. Fixup nr_scanned. */ - if (nr_pages > 1) { + if (nr_pages > 1) sc->nr_scanned -=3D (nr_pages - 1); - nr_pages =3D 1; - } activate_locked: - /* Not a candidate for swapping, so reclaim swap space. */ - if (folio_test_swapcache(folio) && - (mem_cgroup_swap_full(folio) || folio_test_mlocked(folio))) - folio_free_swap(folio); - VM_BUG_ON_FOLIO(folio_test_active(folio), folio); - if (!folio_test_mlocked(folio)) { - int type =3D folio_is_file_lru(folio); - folio_set_active(folio); - stat->nr_activate[type] +=3D nr_pages; - count_memcg_folio_events(folio, PGACTIVATE, nr_pages); - } + folio_activate_locked(folio, stat); keep_locked: folio_unlock(folio); keep: --=20 2.55.0 From nobody Fri Sep 25 23:12:14 2026 Received: from outbound.st.icloud.com (st-2005g-snip4-2.eps.apple.com [57.103.79.25]) (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 7A37338836E for ; Sun, 20 Sep 2026 14:25:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=57.103.79.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914336; cv=none; b=be1ppnTyIYwBlBvVO60NGQuFdfQUsYGAw6oq10ByFsIo8TqB22g2/MVqBwPGryiTr0gg/+LS67rJgFvRz69mr7hFHUwjtfRhywpP0QkMbHP+qUvg32lBJJZO6k0Ah3VygU7d+4CEF94RuYq2CaC/UeaqeJYzqtQeWzKa64tKQI0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914336; c=relaxed/simple; bh=6qsxoupjTP78GIxdHhJCYOj8CeZ1p0lb1VBzMh5O0lk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KkWYlXPPQJz5K1gllGMhGd9fb4qX8pdGuwLmb2x538iUJUQgK245JaPJjjdhRdk9VaoJrvLCye8vv5KVid595hOt5rbIQPTXCD03OuSBeDKPMvD1cAavr3GYhiMW+ibDgNdf0BqQmDWrLMnfSdWk9RnmCJw8yY1b/itCAhiwQ1s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com; spf=pass smtp.mailfrom=icloud.com; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b=RsdGaTtH; arc=none smtp.client-ip=57.103.79.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=icloud.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b="RsdGaTtH" Received: from outbound.st.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPS id E09B61800BD3; Sun, 20 Sep 2026 14:25:32 +0000 (UTC) X-ICL-RepId: 01a0bf35-3eef-76f7-affb-bdfa3850bd61 X-ICL-Out-Info: HUtFAUMEWwJACUgBTUQeDx5WFlZNRAJCTQhKB0MGWQReCEsEQwFbEhVdRUkERxtXAlQXXQZSEnIZWhRcGFNFUR9UWFUJCgJRHFYNV0NUBF9QSxsOXABLWhVVFw4CQh9QH0wWV0NEHxwZWhRcGFNFUR9UWEMZRVZpQQtPHV0ZWxxCZFhXCQoCURxWDVdDVARfUFQRV1ALWQJCD0gKXwdGRB1KG1IDGhlXFlgbRwJFRkRBFEoeCFRbBhQOSVAPAF0DME0dXQ5SBUZeWhdeUxcfSwBcRVoOWwRHFA== Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com; s=1a1hai; t=1789914333; x=1792506333; bh=UnK6ar0vdpcJ83fX60CmWT9hJg4h0FrTaZNGdd2kMoQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:x-icloud-hme; b=RsdGaTtHGC9EUPcCnhq0NmbX4P8wBR3DB70FjUI/smNOV2Cv2HPD6LPSEAqb3TA7in78d1nxZ6c4h4f27RY6TeP5k/uF8GWxTV/GDE9ctGDlL9an82BOZl0X3dVtBnCuGqTYTbYjpKnYpkoifVBgYGYGH7XZlekoXAJAILomYbpQuf1/U5XfP7ERoQ0GoI1CzQIY0ZlqnQJuzg/uuNFlJ4BIEOR98jOWLK3t0RrrTM/0gCVa0KmmVhlsHjlkEPRHndNOL6VjoVWY1317hrzDVeVhXWpLk60NOuTt/fdTp/U3G2BRywnrdXh7kJkj51MDwzg68RDxqEciBW8acEqWiA== Received: from [127.0.0.1] (unknown [17.156.216.30]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPSA id 507201800BCC; Sun, 20 Sep 2026 14:25:27 +0000 (UTC) From: Zhang Peng Date: Sun, 20 Sep 2026 22:24:15 +0800 Subject: [PATCH 2/4] mm/vmscan: extract folio reclaim freeing from shrink_folio_list() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260920-vmscan-refactor-v1-2-ec04d71cb761@tencent.com> References: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> In-Reply-To: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> To: Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Baoquan He , Baolin Wang , Johannes Weiner , David Hildenbrand , Michal Hocko , Lorenzo Stoakes Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Zhang Peng X-Mailer: b4 0.16.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTIwMDIxMCBTYWx0ZWRfXwCqadkKbx2bn xuLwADAYj95SdhAGOAcXFhN62BQQ/9fuBEv2jd+WlGBR3WL9sEfXYHM3PVNKDzMtbiQABc3zCnJ f37RwerIpCky4Lc/rfLDwpzI2+rLUe7sa/xHDcP4Z8omIPuKR1s0G+A+hOWSC1ZZ8KFmSisIFIi VjVWJY8tyutDINLCooAN6ebF87ukYcZrLkvqgzqwL7gcBvldw9vzDSjM9qu4EXNasZMFzgR6Hcs V8Oxe4+fFTh3dKGRMTUQKjakXwknFn61xtcNH15WgbNdwA14piBRxFTsX/A7IDlO4wyf4nd+yUS WxzlaGjaek3E4W/EXaZrfmeHN/8rS6vyoS6OAdzTJeQMHr3MAq4wW6xGCXiEpo= X-Authority-Info-Out: v=2.4 cv=DJaCIiNb c=1 sm=1 tr=0 ts=6aafecdd cx=c_apl:c_pps:t_out a=oyWFxbOnq+dmhQrAPgaJYA==:117 a=oyWFxbOnq+dmhQrAPgaJYA==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=x7bEGLp0ZPQA:10 a=YE32fvk_ji8A:10 a=VkNPw1HP01LnGYTKEx00:22 a=GvQkQWPkAAAA:8 a=g2Kr-gMdqZl5o2Fzx-IA:9 a=QEXdDO2ut3YA:10 a=J82S1U87d15UFHHUFZS8:22 a=J6hPbylVjWXjVQVODqME:22 X-Proofpoint-GUID: mqXOafUsAJpD_o3H0FeAN_cAHp3fOALx X-Proofpoint-ORIG-GUID: mqXOafUsAJpD_o3H0FeAN_cAHp3fOALx X-JNJ: AAAAAAABCiLVt795WGKO9TjdGYKasr/k2G08BTTff7nTgoRri5Fadf2+CvaJwIsim1oQ3fRkUe3nSz3fuXMgumHXqu/G3I2sRagvOgnTCA5BCTvTt0YTclli6Bb6zv+/paJbqwe04vyz6ssCXz049Kmdl+eaBkiJfhSEQZ4nxnbd7SrjlA8MgK0pAUgPmIIw73uJAMul3PE20rO5ygb2TBB4iNxnxJ03/leeuq/3lcY2/Qazz0z5D17S8F9KtayTTKlhKqcr+ttP5lqT7I/31awgzDHcS3oWPAJvfALN2vmz0LqXTyL6wTU4ht4yfvtTxH8CTs1GiTuh+JvmLJs/0pUGFrgPpHoYqqFgJTbVe5hHg/PWx0f+sVeaPkTdx/JHcFDBf/s0Pe3upb4zw7zotTCQfu1//Slp+gzsLqoSlqwFKZcJrjsrtM7w3GjTJdH2Rg0NttbakwpF7PIB6ggkjy3FrJjxAEbFqO+mPPpPGn+4CmecIkc+zukw4hJI27QpNWNXjGt/rSGsXsr4Ul9luR0nt8RYk7xSDX/4pQwQKB0QFd26MjXYsP7h//NTKnIIvzNFqx35ssHyIqzG/ZCCsyjmQmHG/SW5MTwQCCb5jIW5KJELga4p1puzjS/2x0iLttSmAFQGUdsQ5qWSN2mOn5Cfkthq6+7egvu1SwElTA5oXg2cOLRe1HRKxCgrlcSQOhFyW/w/mubniGCfQFiwjTxI7DYXVcv5cl0D8P1cD42dWaIRISV+qj67m/1gmzR/TlrM+cskk2DTggZa5rbhj49ijmdXGOClha9oHOV+mvr7AcvU6tXNoqytqcgHjjPfkrWbnfyJknUGQ6DZ5zRzj28BpZTd/9WKQ+3g+MuNejp7oxrN6+wgH+YEjsx7YrpM2uIoovmkvlSiF412JEylfLf/HtxqueTUzg== From: Zhang Peng shrink_folio_list() contains a self-contained folio-freeing section: buffer release, lazyfree, __remove_mapping(), and folio_batch draining. Extract it into folio_try_reclaim_free() to reduce the size of shrink_folio_list() and make the freeing step independently readable. Return an explicit result so the caller retains the distinction between activating a folio, keeping it on the inactive list, and reclaiming it. The helper leaves the folio locked when it returns ACTIVATE or KEEP and consumes it when it returns SUCCESS. No functional change. Signed-off-by: Zhang Peng Suggested-by: Kairui Song --- mm/vmscan.c | 171 ++++++++++++++++++++++++++++++++++----------------------= ---- 1 file changed, 96 insertions(+), 75 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index c6beca88079a..120085dfa2fe 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1177,6 +1177,95 @@ static void folio_activate_locked(struct folio *foli= o, } } =20 +enum folio_reclaim_result { + FOLIO_RECLAIM_KEEP, + FOLIO_RECLAIM_ACTIVATE, + FOLIO_RECLAIM_SUCCESS, +}; + +static enum folio_reclaim_result folio_try_reclaim_free(struct folio *foli= o, + struct folio_batch *free_folios, + struct scan_control *sc, + unsigned int *nr_reclaimed) +{ + const unsigned int nr_pages =3D folio_nr_pages(folio); + struct address_space *mapping =3D folio_mapping(folio); + + /* + * If the folio has buffers, try to free the buffer mappings + * associated with this folio. If we succeed we try to free + * the folio as well. + * + * We do this even if the folio is dirty. + * filemap_release_folio() does not perform I/O, but it is + * possible for a folio to have the dirty flag set, but it + * is actually clean (all its buffers are clean). This + * happens if the buffers were written out directly, with + * bh_submit(). ext3 will do this, as well as the blockdev + * mapping. filemap_release_folio() will discover that + * cleanness and will drop the buffers and mark the folio + * clean - it can be freed. + * + * Rarely, folios can have buffers and no ->mapping. These + * are the folios which were not successfully invalidated in + * truncate_cleanup_folio(). We try to drop those buffers + * here and if that worked, and the folio is no longer + * mapped into process address space (refcount =3D=3D 1) it can + * be freed. Otherwise, leave the folio on the LRU so it is + * swappable. + */ + if (folio_needs_release(folio)) { + if (!filemap_release_folio(folio, sc->gfp_mask)) + return FOLIO_RECLAIM_ACTIVATE; + + if (!mapping && folio_ref_count(folio) =3D=3D 1) { + folio_unlock(folio); + if (folio_put_testzero(folio)) + goto free_it; + + /* + * Rare race with speculative reference. The + * speculative reference will free this folio + * shortly, so we may increment nr_reclaimed here + * and leave it off the LRU. + */ + *nr_reclaimed +=3D nr_pages; + return FOLIO_RECLAIM_SUCCESS; + } + } + + if (folio_test_lazyfree(folio)) { + /* follow __remove_mapping for reference */ + if (!folio_ref_freeze(folio, 1)) + return FOLIO_RECLAIM_KEEP; + /* + * The folio has only one reference left, which is + * from the isolation. After the caller puts the + * folio back on the lru and drops the reference, the + * folio will be freed anyway. It doesn't matter + * which lru it goes on. So we don't bother checking + * the dirty flag here. + */ + count_vm_events(PGLAZYFREED, nr_pages); + count_memcg_folio_events(folio, PGLAZYFREED, nr_pages); + } else if (!mapping || !__remove_mapping(mapping, folio, true, + sc->target_mem_cgroup)) + return FOLIO_RECLAIM_KEEP; + + folio_unlock(folio); +free_it: + VM_WARN_ON_ONCE_FOLIO(folio_ref_count(folio), folio); + *nr_reclaimed +=3D nr_pages; + + folio_unqueue_deferred_split(folio); + if (folio_batch_add(free_folios, folio) =3D=3D 0) { + mem_cgroup_uncharge_folios(free_folios); + try_to_unmap_flush(); + free_unref_folios(free_folios); + } + return FOLIO_RECLAIM_SUCCESS; +} + /* * shrink_folio_list() returns the number of reclaimed pages */ @@ -1564,83 +1653,15 @@ static unsigned int shrink_folio_list(struct list_h= ead *folio_list, } } =20 - /* - * If the folio has buffers, try to free the buffer - * mappings associated with this folio. If we succeed - * we try to free the folio as well. - * - * We do this even if the folio is dirty. - * filemap_release_folio() does not perform I/O, but it - * is possible for a folio to have the dirty flag set, - * but it is actually clean (all its buffers are clean). - * This happens if the buffers were written out directly, - * with bh_submit(). ext3 will do this, as well as - * the blockdev mapping. filemap_release_folio() will - * discover that cleanness and will drop the buffers - * and mark the folio clean - it can be freed. - * - * Rarely, folios can have buffers and no ->mapping. - * These are the folios which were not successfully - * invalidated in truncate_cleanup_folio(). We try to - * drop those buffers here and if that worked, and the - * folio is no longer mapped into process address space - * (refcount =3D=3D 1) it can be freed. Otherwise, leave - * the folio on the LRU so it is swappable. - */ - if (folio_needs_release(folio)) { - if (!filemap_release_folio(folio, sc->gfp_mask)) - goto activate_locked; - if (!mapping && folio_ref_count(folio) =3D=3D 1) { - folio_unlock(folio); - if (folio_put_testzero(folio)) - goto free_it; - else { - /* - * rare race with speculative reference. - * the speculative reference will free - * this folio shortly, so we may - * increment nr_reclaimed here (and - * leave it off the LRU). - */ - nr_reclaimed +=3D nr_pages; - continue; - } - } - } - - if (folio_test_lazyfree(folio)) { - /* follow __remove_mapping for reference */ - if (!folio_ref_freeze(folio, 1)) - goto keep_locked; - /* - * The folio has only one reference left, which is - * from the isolation. After the caller puts the - * folio back on the lru and drops the reference, the - * folio will be freed anyway. It doesn't matter - * which lru it goes on. So we don't bother checking - * the dirty flag here. - */ - count_vm_events(PGLAZYFREED, nr_pages); - count_memcg_folio_events(folio, PGLAZYFREED, nr_pages); - } else if (!mapping || !__remove_mapping(mapping, folio, true, - sc->target_mem_cgroup)) + switch (folio_try_reclaim_free(folio, &free_folios, sc, + &nr_reclaimed)) { + case FOLIO_RECLAIM_ACTIVATE: + goto activate_locked; + case FOLIO_RECLAIM_KEEP: goto keep_locked; - - folio_unlock(folio); -free_it: - /* - * Folio may get swapped out as a whole, need to account - * all pages in it. - */ - nr_reclaimed +=3D nr_pages; - - folio_unqueue_deferred_split(folio); - if (folio_batch_add(&free_folios, folio) =3D=3D 0) { - mem_cgroup_uncharge_folios(&free_folios); - try_to_unmap_flush(); - free_unref_folios(&free_folios); + case FOLIO_RECLAIM_SUCCESS: + continue; } - continue; =20 activate_locked_split: /* --=20 2.55.0 From nobody Fri Sep 25 23:12:14 2026 Received: from outbound.st.icloud.com (st-2005j-snip4-11.eps.apple.com [57.103.79.123]) (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 4E9E6379C4F for ; Sun, 20 Sep 2026 14:25:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=57.103.79.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914346; cv=none; b=VqaqYM5emWz5U/q4XPEjNMYI/wS+6fqOkS+eamK9/NOouuM9u2g9Y1zhFTEvu8LNfoRtVIi/etjkYfr+0ke5l9Zjp6RX3x04RmtIGQXbMK2ECa1AcuoAGl5o0FX65VHHZHDqjDrlwgwsanuVdL+rpzwiFK5KzAvn+Repb2D7Bvw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914346; c=relaxed/simple; bh=f342N/c8+dEDJDWraNU2OVkQeSo31UDlhHfw7nORPhE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HNYHaZAjh2mZtxfGuN5DLtT4MCsNWECFJaYxWYVtyY8hN+9kAHXGw/O/1eS4ZKzJUIttbs4PE5/AFNsj+B5gY7R7HJInLEdBjGXkfGYbHA35+y/wLGmDo1CJKENgnaXT2G3tOVKBmXQxXjQptpC7Z6Bqh9B2fym4F8NsGxqsL8I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com; spf=pass smtp.mailfrom=icloud.com; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b=WQgQc6Sf; arc=none smtp.client-ip=57.103.79.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=icloud.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b="WQgQc6Sf" Received: from outbound.st.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPS id 99F261800297; Sun, 20 Sep 2026 14:25:41 +0000 (UTC) X-ICL-RepId: 01a0bf35-60c5-75c9-8b47-8dffd66b0e93 X-ICL-Out-Info: HUtFAUMEWwJACUgATUQeDx5WFlZNRAJCTQhKB0MGWQReCEsEQwFbEhVdRUkERxtXAlQXXQZSEnIZWhRcGFNFUR9UWFUJCgJRHFYNV0NUBF9QSxsOXABLWhVVFw4CQh9QH0wWV0NEHxwZWhRcGFNFUR9UWEMZRVZpQQtPHV0ZWxxCZFhXCQoCURxWDVdDVARfUFQRV1ALWQJCD0gKXwdGRB1KG1IDGhlXFlgbRwJFRkRBFEseCFRbBhQOSVAPAF0DME0dXQ5SBUZeWhdeUxcfSwBcRVoOWwRHFA== Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com; s=1a1hai; t=1789914344; x=1792506344; bh=5pw+tpdHx2j/84yt3i8Fgf/shxRk6ErVktUyAKNdLp4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:x-icloud-hme; b=WQgQc6SfBU1UTStyIAAHOgOXwoYXMfQzpHOvzXm9IHBmMIbz2YcQnssNwdomRlhZcSVIYKLlZxSnrXYTLFwwYetyubsGxM+RHTByhTnUhkwhvNMSc9dHGXPQnoxFzytkIhJCNTEHt6SRtzMrEJu+g9Z3+hIs/YbXtvLo4SnvtbTr4Du6Z1Qmhcs7KXoYPNRoHWg1imQrC2O8pIerTGswULO1lREstEw8yKLP+Bk+4OqKiuoVDp3AStlipTBS088F5LAvqiCV58ft1B4K1977IwJWs2e5nlNveYsmljdUpX/9vrSrVZHRgcI7htP3LMT3SByMwd/NkjNYTOdfGTQ92g== Received: from [127.0.0.1] (unknown [17.156.216.30]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPSA id C7131180028A; Sun, 20 Sep 2026 14:25:33 +0000 (UTC) From: Zhang Peng Date: Sun, 20 Sep 2026 22:24:16 +0800 Subject: [PATCH 3/4] mm/vmscan: extract folio pageout from shrink_folio_list() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260920-vmscan-refactor-v1-3-ec04d71cb761@tencent.com> References: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> In-Reply-To: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> To: Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Baoquan He , Baolin Wang , Johannes Weiner , David Hildenbrand , Michal Hocko , Lorenzo Stoakes Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Zhang Peng X-Mailer: b4 0.16.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTIwMDIxMCBTYWx0ZWRfXwXrX+1CQ9OqP qilit9DWHNxX4siHZVf6yDfELsJncHnl1Wz2qrUCrtD5BkDyowPT93npjQEtO59kiJTf456CAAr ZZIRJwAnM2UT0chAQ5i0V+F+hmeKfJl+3SHm7h86FYoZpU/mKff54IZZuFTGl/jHVHPPg8JULDO CZYJRkqZGE/TrJhrTaFgxKa8GiVzgt0SVbhzvYwB6bKOHELfdZAVC/86BfaOpZtHlHqGIGbWhnO hR9crLe0LUsT0rjYdR5TaXASz9rhqdM4lhbCTEHPUTPK3oy5E4+e4FFyIRw85fWHJ/sidiVtBMQ NgQVIsiSuVTbqIAQkIu9xLQxkcwBU3aE81FQQf7HdKKhxLILE2vENci9/Ifsbg= X-Proofpoint-GUID: XofwOTYfrX-FMP0KpQDBM3g2zGkwMuyn X-Authority-Info-Out: v=2.4 cv=R/8O2NRX c=1 sm=1 tr=0 ts=6aafece6 cx=c_apl:c_pps:t_out a=oyWFxbOnq+dmhQrAPgaJYA==:117 a=oyWFxbOnq+dmhQrAPgaJYA==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=x7bEGLp0ZPQA:10 a=YE32fvk_ji8A:10 a=VkNPw1HP01LnGYTKEx00:22 a=GvQkQWPkAAAA:8 a=qi0cjtEbl7ftujh0onEA:9 a=QEXdDO2ut3YA:10 a=J82S1U87d15UFHHUFZS8:22 a=J6hPbylVjWXjVQVODqME:22 X-Proofpoint-ORIG-GUID: XofwOTYfrX-FMP0KpQDBM3g2zGkwMuyn X-JNJ: AAAAAAABG7IOrnmuE+3ctHcDD1SpVCi8wFd7Y1nUCln3xQ4L7NRy+RFuTFtVb17auVdCj1wVa8U6mbkl2n05vciIle+2zIfFgbd/WaPl5grtx2yf9Di2w6fdDmUGGVhr3F8aiyZ1c33YFzc0f5JFcgLCnUEd6igfR+KNYSIuH1E5sOwDTw7uBu/oddl/5g2uOOL54ASip20vvRObHg/+tLBg3utbeAHfvuqnvaTdHi5ut8BC3364ZyTmwDLfXkNefSpgk8kmpKYBX3DEOBBRu2WNbtgFo+nIESMDsnUeJZ2jEyRW5eb02eOcyHrYsKGIg5MHYptGtOLryTSvqhG9y3WE7T2m7bd1tLr/qI6OpnLxjZA5iPHi2Em/KA6F31EXGETlhygko5tpuZQi6lqZTABbAzUgE/hxZHkBJVV26ayVZQ+fnf2H/GmGh1jKGSHZ+ewyRqv+TdEilJus4wAwHa1UFbBn5SiDw3xY2/4hlEF7Km+h8Dao+dOYhAdv2ccn1d3inOE1vf9uQuMze9anQ4z+T6jzTZchGsw2hfAdufFbMclgEhfgIFnE9C4aQIVFM5y+YZYqmIxmczZtLSpPgF9sUXpY94o5zYmSWnurj4bNf2dGnJGzdnRZt44hkYkfC8YKJt22jZglXy1IuvBaKmFXkPmY6PQVIGbxgrzfbUq+/Y8tg4+SJjsJBF3soD+mvVSBbEQnwCyH0wSoAVNgGK5IVqMpHxUrBJl5VEU+D0anjidG6msxHyw+jPNB1/gNM1fprrUICmP1gSqoYmQV24ml04CWcvJR10pzEAGtBCqnNqXYQe/Pbfois3PPbCHzU6CQQ0No++pDsArC6qjMIoA7+3cjglmIBUi1kkZGFBynmgEQTsd6QcfPbdfXceSicU3zy94Zeb7cxZzzapYhMku+Q5/rOeVQMob3DmSsknmsrhGtJU/zGw== From: Zhang Peng shrink_folio_list() contains a self-contained pageout() dispatch state machine. Extract it into folio_try_pageout() so it can be reused by the batched pageout path. Return an explicit pageout result instead of a boolean. This keeps the important distinction between activating and merely keeping a folio visible to the caller, and also records whether a kept folio remains locked after pageout(). The clean and synchronous-write cases return FOLIO_PAGEOUT_FREE: the folio is still locked there, and shrink_folio_list() then runs its single folio_try_reclaim_free() call, so the reclaim-free step keeps exactly one caller. The PAGE_ACTIVATE arm no longer normalises nr_pages to 1 after a split: folio_activate_locked() derives the count from folio_nr_pages() itself, which is equal by construction once the folio is order-0. Note this makes the patch depend on patch 1; applying it alone would over-account nr_activate for a split shmem folio. No functional change. Suggested-by: Kairui Song --- mm/vmscan.c | 100 ++++++++++++++++++++++++++++++++++++--------------------= ---- 1 file changed, 61 insertions(+), 39 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 120085dfa2fe..3bce7ff89293 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1266,8 +1266,60 @@ static enum folio_reclaim_result folio_try_reclaim_f= ree(struct folio *folio, return FOLIO_RECLAIM_SUCCESS; } =20 +enum folio_pageout_result { + FOLIO_PAGEOUT_KEEP_LOCKED, + FOLIO_PAGEOUT_KEEP_UNLOCKED, + FOLIO_PAGEOUT_ACTIVATE, + FOLIO_PAGEOUT_FREE, /* folio is locked, hand it to folio_try_reclaim_free= () */ +}; + +static enum folio_pageout_result folio_try_pageout(struct folio *folio, + struct scan_control *sc, struct swap_io_ctx *ctx, + struct list_head *folio_list) +{ + struct address_space *mapping =3D folio_mapping(folio); + unsigned int nr_pages =3D folio_nr_pages(folio); + + switch (pageout(ctx, mapping, folio, folio_list)) { + case PAGE_ACTIVATE: + /* + * If shmem folio is split when writeback to swap, the + * tail pages will make their own pass through this + * function and be accounted then. There is no need to + * clamp nr_pages here: folio_activate_locked() derives + * the count from folio_nr_pages() itself. + */ + if (nr_pages > 1 && !folio_test_large(folio)) + sc->nr_scanned -=3D (nr_pages - 1); + return FOLIO_PAGEOUT_ACTIVATE; + case PAGE_KEEP: + return FOLIO_PAGEOUT_KEEP_LOCKED; + case PAGE_SUCCESS: + if (nr_pages > 1 && !folio_test_large(folio)) + sc->nr_scanned -=3D (nr_pages - 1); + + if (folio_test_writeback(folio)) + return FOLIO_PAGEOUT_KEEP_UNLOCKED; + if (folio_test_dirty(folio)) + return FOLIO_PAGEOUT_KEEP_UNLOCKED; + + /* + * A synchronous write - probably a ramdisk. Go ahead + * and try to reclaim the folio. + */ + if (!folio_trylock(folio)) + return FOLIO_PAGEOUT_KEEP_UNLOCKED; + if (folio_test_dirty(folio) || folio_test_writeback(folio)) + return FOLIO_PAGEOUT_KEEP_LOCKED; + fallthrough; + case PAGE_CLEAN: + return FOLIO_PAGEOUT_FREE; + } + unreachable(); +} + /* - * shrink_folio_list() returns the number of reclaimed pages + * Reclaimed folios are counted in the return value. */ static unsigned int shrink_folio_list(struct list_head *folio_list, struct pglist_data *pgdat, struct scan_control *sc, @@ -1585,7 +1637,6 @@ static unsigned int shrink_folio_list(struct list_hea= d *folio_list, if (folio_maybe_dma_pinned(folio)) goto activate_locked; =20 - mapping =3D folio_mapping(folio); if (folio_test_dirty(folio)) { if (folio_is_file_lru(folio)) { /* @@ -1606,50 +1657,21 @@ static unsigned int shrink_folio_list(struct list_h= ead *folio_list, goto keep_locked; if (!sc->may_writepage) goto keep_locked; - /* * Folio is dirty. Flush the TLB if a writable entry * potentially exists to avoid CPU writes after I/O * starts and then write it out here. */ try_to_unmap_flush_dirty(); - switch (pageout(&ctx, mapping, folio, folio_list)) { - case PAGE_KEEP: - goto keep_locked; - case PAGE_ACTIVATE: - /* - * If shmem folio is split when writeback to swap, - * the tail pages will make their own pass through - * this function and be accounted then. - */ - if (nr_pages > 1 && !folio_test_large(folio)) { - sc->nr_scanned -=3D (nr_pages - 1); - nr_pages =3D 1; - } + switch (folio_try_pageout(folio, sc, &ctx, folio_list)) { + case FOLIO_PAGEOUT_ACTIVATE: goto activate_locked; - case PAGE_SUCCESS: - if (nr_pages > 1 && !folio_test_large(folio)) { - sc->nr_scanned -=3D (nr_pages - 1); - nr_pages =3D 1; - } - if (folio_test_writeback(folio)) - goto keep; - if (folio_test_dirty(folio)) - goto keep; - - /* - * A synchronous write - probably a ramdisk. Go - * ahead and try to reclaim the folio. - */ - if (!folio_trylock(folio)) - goto keep; - if (folio_test_dirty(folio) || - folio_test_writeback(folio)) - goto keep_locked; - mapping =3D folio_mapping(folio); - fallthrough; - case PAGE_CLEAN: - ; /* try to free the folio below */ + case FOLIO_PAGEOUT_KEEP_LOCKED: + goto keep_locked; + case FOLIO_PAGEOUT_KEEP_UNLOCKED: + goto keep; + case FOLIO_PAGEOUT_FREE: + break; /* folio is locked; try to free it below */ } } =20 --=20 2.55.0 From nobody Fri Sep 25 23:12:14 2026 Received: from outbound.st.icloud.com (st-2005k-snip4-8.eps.apple.com [57.103.79.71]) (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 808EF37CD20 for ; Sun, 20 Sep 2026 14:25:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=57.103.79.71 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914354; cv=none; b=gdM6aD2VpOGHLBWlX9COlIeqAz47RQ8e1WKCgUJTHsaiiu4nc5/yRKqBtayfBeMVAyYiv3GiplMclzNz9TsedFCJ1h1VVZjlhX7xgPZ0wEqTdMuVlt2fWDiD6mBJ2U4iWfUno/RW7jw9/S890tCfPScCEAeOrO9MC3KIKckn6K4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789914354; c=relaxed/simple; bh=tEo6bVXi8ijmfaQJGFgnvFbO3uAtkG5mOc5M7f9AKhw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GYwO2fmn9clNrxJwBzw2rm8zz7CJMUmVkmTx/cSPyYecRfGaluGV2mZi2s0RsIQagDtW4Ng5g3ZHuHA2MEPs2iGrl8ZPNU6Xw3Z4iywQRPxGjaWv+tpa4jPiz1TIRltU5OnO0DT5bMXivmPAgBu1L6CT4sGlxrg1onHp5FHnMLw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com; spf=pass smtp.mailfrom=icloud.com; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b=0DjttDuk; arc=none smtp.client-ip=57.103.79.71 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=icloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=icloud.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=icloud.com header.i=@icloud.com header.b="0DjttDuk" Received: from outbound.st.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPS id DAFC81800298; Sun, 20 Sep 2026 14:25:51 +0000 (UTC) X-ICL-RepId: 01a0bf35-88f9-7723-a13b-ddac2a20e3f7 X-ICL-Out-Info: HUtFAUMEWwJACUgBTUQeDx5WFlZNRAJCTQhKB0MGWQReCEsEQwFbEhVdRUkERxtXAlQXXQZSEnIZWhRcGFNFUR9UWFUJCgJRHFYNV0NUBF9QSxsOXABLWhVVFw4CQh9QH0wWV0NEHxwZWhRcGFNFUR9UWEMZRVZpQQtPHV0ZWxxCZFhXCQoCURxWDVdDVARfUFQRV1ALWQJCD0gKXwdGRB1KG1IDGhlXFlgbRwJFRkRBFEweCFRbBhQOSVAPAF0DME0dXQ5SBUZeWhdeUxcfSwBcRVoOWwRHFA== Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com; s=1a1hai; t=1789914352; x=1792506352; bh=y+4LxcE0ZNzlIfE6jsP/r+Z9z994JbQce9sXcvnyNA8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:x-icloud-hme; b=0DjttDukd+i3mo1A1I2YF7SyteZe/7bum5j+GBddC5P0ROkasuWaAkywRCpHku72oPNSZz2SGxUjajVIRh7JommRICypJYrbZNZG3lfJOGAm9fUQOLwfUv5LaWMD31LtCShooxE0IuBz7ckhptCUtDuH7wCV/fMflXMKwWwN1zLbXTR6wDnVtYgvsLzKaon53p5qhDBy0tJYFvhmydaSPJ9I2CuaP6snHI4NwiXOMe7Ao0m0PMLSs6/Q58OVs8Zwmy7LRHlJN+1z+WcZyERmm9OmloBj59F4LQI+gA+zCCcwUqhtWlNONp0gIDxZTvp9NBiLOwdKyBcnWJRk8t+IlA== Received: from [127.0.0.1] (unknown [17.156.216.30]) by p00-icloudmta-asmtp-us-east-1a-60-percent-7 (Postfix) with ESMTPSA id AE6C618002AE; Sun, 20 Sep 2026 14:25:41 +0000 (UTC) From: Zhang Peng Date: Sun, 20 Sep 2026 22:24:17 +0800 Subject: [PATCH 4/4] mm/vmscan: extract folio unmap logic into folio_try_unmap() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260920-vmscan-refactor-v1-4-ec04d71cb761@tencent.com> References: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> In-Reply-To: <20260920-vmscan-refactor-v1-0-ec04d71cb761@tencent.com> To: Andrew Morton , Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Baoquan He , Baolin Wang , Johannes Weiner , David Hildenbrand , Michal Hocko , Lorenzo Stoakes Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Zhang Peng X-Mailer: b4 0.16.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTIwMDIxMCBTYWx0ZWRfX7qNKLx881oKO Bp+LChKGf2VW5KvHE+LIrzqNhgkEFk+8+IT8an4O1FJ7uX+mrx7XS3BSa9pvZZrRFo0ujF3KTr7 PfYqGylSL61VuAq1uHGnPvG8GJVhl9cTlTs3h1rNsx3KDgyXy9eAQ8g5Y8IQhH1DXKZhWGgRfkh wnqHg1ZriRyjUdeHm/1FtRTUHY6jfPg1d6PFEdpCxFkIEfnPZ6ME+r1boiadHkzu6yVr7F8DAx2 7yePeiwa+eH5ONJJRiVMrpblmeQKWgtVeWcJADZbQDqDOg8dsRQydpYTYyp46SOg5bTMTkzE/dz LD1EjemTVVxJkwLMAgI4un8rxYU/d/N2WNQ7wssnZrkpHx6ZpN3X/mK0g8XBNk= X-Proofpoint-GUID: hsmcGXTx_XoKWvLdLUk8nhQZ7yr68fs8 X-Proofpoint-ORIG-GUID: hsmcGXTx_XoKWvLdLUk8nhQZ7yr68fs8 X-Authority-Info-Out: v=2.4 cv=aOr9aL9m c=1 sm=1 tr=0 ts=6aafecf0 cx=c_apl:c_pps:t_out a=oyWFxbOnq+dmhQrAPgaJYA==:117 a=oyWFxbOnq+dmhQrAPgaJYA==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=x7bEGLp0ZPQA:10 a=YE32fvk_ji8A:10 a=VkNPw1HP01LnGYTKEx00:22 a=GvQkQWPkAAAA:8 a=VwQbUJbxAAAA:8 a=Oe3AU6d8b7fpH-gKf6sA:9 a=QEXdDO2ut3YA:10 a=J82S1U87d15UFHHUFZS8:22 a=J6hPbylVjWXjVQVODqME:22 X-JNJ: AAAAAAABexOQ5G1UmVTm5NChbqSVvjY4dKgF+1/+LdvMSuutUNKOVn8DqWDfmzPGkYwCgcYUrOXT1Zy/EUORdYYUYEV1GN5Rhh/0Sh02N+/PV12GIHCgjZcr4DQx8cUi32GomQIUICU6YR2OVOy7coC8/rEX3AmQS3WV62G+EGBQjP1lY3rO/solOdeBJyyPZBBBSktw7jjhGkSJpXm5G1Cogosjl3kDnbRRYMUeVXtJvVIkhO6P12Onk76bZD0LK04/9Atv2qGO1hbAnTJmGr+iQqPDLOTTmUfxX+4qsMGPHFLaSIlylxdYTQ/9fuKmnvVVdhddWZMx8ZR5PRH1RQE4crSD7oa81BgtUolF0pLrnMJ1KaYo6gwr4zj0ChxqQFyvskztMJ+BOmRXdHp6J2YYuQ/e9quypXxktlpwLghBzV8z3cvXwBwhWdC6i08ixkMB5ciyFILygON0h7NWockcRamEEiDBw+UZKQdVloz5+jBfBM0xb1BgAfXPWjCa6cSy+dcnCiL+CXtoxrM5ggNQG34oOsEcuA5kz80kGcpnf0Ynj0/mq+QQTkPeHem4xQiQ/JBffPCXW5q0UA6GnMOvfpS2qNxMx8+qN8dSJ8n0FPkqQX0yVrjSRQjvk9USiSzUqswCSKJDxvSqUwAmQZCiYioAwaYbGo6N4aAhhe+RmBPDldebg6O2nuzyM9kzr6HhaJWBC8LJpRw7MnXsPlrZrZw2rHgqzmdu7E+E6uHd/Mi+HXyNOloE8cKthcuI12xpTu8vvbKrRuNHyMbUcybvC/LSdBmdS7Ons+Auduerqu7BQxUeeNYNMIHprLp7BV1AYALfnQNfp1K831zocdUElwxySKmJvm1+pmUqQKfONVJX6gf0g0NUJDwH8zJlszWn/wYb3L5kNbVgP9EViUve1L3ZpEs= From: Zhang Peng shrink_folio_list() contains a self-contained block that sets up TTU flags and calls try_to_unmap(), accounting for failures via reclaim_stat. Extract it into folio_try_unmap() to reduce the size of shrink_folio_list() and make the unmap step independently readable. folio_try_unmap() is only called when the folio is actually mapped; the !folio_mapped() check stays in the caller, keeping the function's semantics clear: it tries to unmap a mapped folio and returns whether the unmap succeeded. No functional change. Reviewed-by: Barry Song Signed-off-by: Zhang Peng Suggested-by: Kairui Song --- mm/vmscan.c | 65 +++++++++++++++++++++++++++++++++------------------------= ---- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 3bce7ff89293..71b507011603 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1318,6 +1318,38 @@ static enum folio_pageout_result folio_try_pageout(s= truct folio *folio, unreachable(); } =20 +static bool folio_try_unmap(struct folio *folio, struct reclaim_stat *stat, + unsigned int nr_pages) +{ + enum ttu_flags flags =3D TTU_BATCH_FLUSH; + const bool was_swapbacked =3D folio_test_swapbacked(folio); + + if (folio_test_pmd_mappable(folio)) + flags |=3D TTU_SPLIT_HUGE_PMD; + /* + * Without TTU_SYNC, try_to_unmap will only begin to hold PTL + * from the first present PTE within a large folio. Some + * initial PTEs might be skipped due to races with parallel + * PTE writes in which PTEs can be cleared temporarily before + * being written new present values. This will lead to a large + * folio is still mapped while some subpages have been + * partially unmapped after try_to_unmap; TTU_SYNC helps + * try_to_unmap acquire PTL from the first PTE, eliminating the + * influence of temporary PTE values. + */ + if (folio_test_large(folio)) + flags |=3D TTU_SYNC; + + try_to_unmap(folio, flags); + if (folio_mapped(folio)) { + stat->nr_unmap_fail +=3D nr_pages; + if (!was_swapbacked && folio_test_swapbacked(folio)) + stat->nr_lazyfree_fail +=3D nr_pages; + return false; + } + return true; +} + /* * Reclaimed folios are counted in the return value. */ @@ -1596,36 +1628,9 @@ static unsigned int shrink_folio_list(struct list_he= ad *folio_list, * The folio is mapped into the page tables of one or more * processes. Try to unmap it here. */ - if (folio_mapped(folio)) { - enum ttu_flags flags =3D TTU_BATCH_FLUSH; - bool was_swapbacked =3D folio_test_swapbacked(folio); - - if (folio_test_pmd_mappable(folio)) - flags |=3D TTU_SPLIT_HUGE_PMD; - /* - * Without TTU_SYNC, try_to_unmap will only begin to - * hold PTL from the first present PTE within a large - * folio. Some initial PTEs might be skipped due to - * races with parallel PTE writes in which PTEs can be - * cleared temporarily before being written new present - * values. This will lead to a large folio is still - * mapped while some subpages have been partially - * unmapped after try_to_unmap; TTU_SYNC helps - * try_to_unmap acquire PTL from the first PTE, - * eliminating the influence of temporary PTE values. - */ - if (folio_test_large(folio)) - flags |=3D TTU_SYNC; - - try_to_unmap(folio, flags); - if (folio_mapped(folio)) { - stat->nr_unmap_fail +=3D nr_pages; - if (!was_swapbacked && - folio_test_swapbacked(folio)) - stat->nr_lazyfree_fail +=3D nr_pages; - goto activate_locked; - } - } + if (folio_mapped(folio) && + !folio_try_unmap(folio, stat, nr_pages)) + goto activate_locked; =20 /* * Folio is unmapped now so it cannot be newly pinned anymore. --=20 2.55.0