From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 CA08D517BC6 for ; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804735; cv=none; b=fSz/ER1zFEwc+H2ycObJ2JZ6wbyuD05u0qHxjXAUsyOpmhDrsc7SQk3OAe4RbCOxAYAIRUqt2rS7bjgWVjRvTjnXk3cq2pP1Sf7ZAXPbsS99sUhuHYeStH5ftb5mP7us6tTMLdV2yNIK/80/MRnqnbVaC9aOWoJoPdBVyj7xh3k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804735; c=relaxed/simple; bh=WHjZ3MtkzfeirCgRiKk2+BAR2kgb6CdSW7hILNlYFUk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P5mAauTZNGyAs360vvAoV1ai2dY6wimcNNblDl0rNRzPofiV2AtnOOoht95ISLV5aa5OuQT7SbF/2a3uZ8woLTVifAwp9DP1mpOUoSKtgXke70xFsI/jdrrej9pV5GF/jir7Z6ycBbKCWEW5X9yzsrBPEEBmrlxTB9kbDS4fWDI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mudKBYil; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mudKBYil" Received: by smtp.kernel.org (Postfix) with ESMTPS id 65378C2BD01; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804735; bh=WHjZ3MtkzfeirCgRiKk2+BAR2kgb6CdSW7hILNlYFUk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=mudKBYilZletaWrVKoQQInwp3bT2uXJKxuncY/eT5dmk22y0hJBpViIGoBhueINsF rB0GBgdFFPzB+fNG99onFvQM501aHSWtPfU9ExKApir680ztzaHmT8xKaf2oc4PEdQ Koi8PwKOc/CeFLj1Clb351r+LX2dJRFdnjbbT7HNHCC8ZvYQ4gQMCrN5Mwdj7Q7tOW zuTqnkEOSDPKDadt2gVCIpBEpII47drKAkgm/dCmotMWq9dyL21eJ2oiiY2h7egsTI ypQMK9YNPcJZ0qfNKV/ejaFXmJmCYu6MwAXjbi28qOBQbkxvFYDWPjF5ETUCH3Kc69 I0PEBmpGy5Low== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39C7BC79F99; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:05 +0800 Subject: [PATCH v4 01/17] mm/swap: fix off-by-one in swap cache replace sanity check 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: <20260908-swap-thp-cleanup-v4-1-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=1650; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=XESq4kPupCnQj7r95GN7GoyviZFWLnOgj/AyzSIJFVc=; b=jCvUgn3rqoALZFvFG741d+xlfd7OfXxx2iN9tamlvi9M5ApOra3C9c7uG/LVbC8Ashsz4inbx PflnFhzqkucB/1VIZSkU7zQDUvf4EHyKiTVtmWkERcsqB9nwr2zsviO X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song The DEBUG_VM sanity check in __swap_cache_replace_folio() iterates the old folio's range with "while (ci_off++ < ci_end)", so the loop body runs on the already-incremented offset: the first entry is skipped and one entry past the range is read. For a folio split that entry belongs to the first after-split folio and was just repointed by the replacement loop above, so the check would warn spuriously whenever sub-folio orders differ from the head folio's. Currently we don't support non-uniform swapcache split, but this still needs a fix to clean it up and prepare for non-uniform swap cache split. Use the same do-while pattern as the replacement loop. Fixes: 8578e0c00dcf ("mm, swap: use the swap table for the swap cache and s= witch API") Acked-by: Zi Yan Reviewed-by: Barry Song Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun Acked-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- mm/swap_state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/swap_state.c b/mm/swap_state.c index 305877e1f4d7..2cf7ed2a4df4 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -389,8 +389,9 @@ void __swap_cache_replace_folio(struct swap_cluster_inf= o *ci, folio_order(old) !=3D folio_order(new)) { ci_off =3D swp_cluster_offset(old->swap); ci_end =3D ci_off + folio_nr_pages(old); - while (ci_off++ < ci_end) + do { WARN_ON_ONCE(swp_tb_to_folio(__swap_table_get(ci, ci_off)) !=3D old); + } while (++ci_off < ci_end); } } =20 --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 C9FA74CB8D3 for ; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804735; cv=none; b=BrV1BfE7XLwJBN/rMuEAPq9RDtq7XQvJReJghesLwiD56by72D89KK0vcFUJlg6MAe3v+jf5+4rig4030GJbOHom6/lpdEUm66XKI4ueA+Tu8GNsLQTW0EpQ8Faij+sqj5uTil6Ig/srDl7q+BdMZIztURQq7fDlfb8Rvs3qTdk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804735; c=relaxed/simple; bh=IDfifzVDX7G7viE/LmtLdKn2cI+UIgXIHfXd8smD3lY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=axa/3YdE1zATs2cIVno3LbdN+bT12SL1G18YsMyFgXmxHeIVHF4JBsez4QDz2sh7GS9z7RmACHDergocaQ5khWPGrf5L0LeYgoIOL922wgLz7DDU+R2oJ2RcjGgZ8QXRJJQ2ZLRyx/Yebzh6WuoTgdJGsF16i3rCWey8WlyO9Iw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Vnsvxr1l; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Vnsvxr1l" Received: by smtp.kernel.org (Postfix) with ESMTPS id 9AB93C2BCC7; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804735; bh=IDfifzVDX7G7viE/LmtLdKn2cI+UIgXIHfXd8smD3lY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Vnsvxr1lDgoBQYmwSW7VmkoH0LieQf/XuGfeoZD+IFvPZdguA4vmaBSM2MAoRfpJ0 OkbelQ3BCm8a6BHNv7ltdRq6Y1M0ovxrjBx3TItHcx5TZ36t6wetsdKJglF2AyAAHj ZJmIZuyxCwKROjJyqt+hPAMbz/+dv2FZ55GPy2LGgZRF+/O5PcvnLkYR7NcBxDItww VTcmH2A9psbf18Sxb32BdJFh5TZ4zpScwzMEl+FnJ6BGOjtemdaU+KQ4UbB9jmMLTo gM81XRkUSVSu0gBLhRHtlNDAVrZ9vqGDgweoeZ0h/oKOxjwZF20wMe4kd3mVamYW5U XYuY6BKT2mTIw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8335BC79FA0; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:06 +0800 Subject: [PATCH v4 02/17] mm/huge_memory: fix rejection of swap cache folios with a mapping 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: <20260908-swap-thp-cleanup-v4-2-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=3844; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=aGhq09lUEoI1Oa1/if3OnIL3d1mjAB+qZOuhjPWgUVU=; b=IgkPvdneM1y3bgJTUhiPdjWb48wjKoHlWdkkNqF1r1wiKRZLuWU65Kn4eAoRSqeHKKSeBqVUp ryz8vdoT1UgBpwk0feG2osMiY5KNHAXA14oC2JxPFUuaJPHtJSKWAGs X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song A folio in the swap cache cannot be split if it has a mapping (shmem). The split code does a defensive check for this in __folio_freeze_and_split_unmapped, after the folio ref has been frozen and the NR_SHMEM_THPS/NR_FILE_THPS counters have been decremented. It rejects the split and returns -EINVAL without unfreezing the folio or restoring the counters. That error path is buggy, if it is ever taken. It leaves the folio frozen and stuck, skews the counters, and fires the VM_WARN_ON_ONCE_FOLIO for a state that is actually legitimate. Check for this case up front in folio_check_splittable and return -EBUSY before any state is modified, so the split routine always backs out cleanly. Also fix a bracket style issue that checkpatch.pl keeps complaining about. Fixes: 00527733d0dc ("mm/huge_memory: add two new (not yet used) functions = for folio_split()") Fixes: 714b056c8321 ("mm/huge_memory: convert VM_BUG* to VM_WARN* in __foli= o_split") Reviewed-by: Zi Yan Reviewed-by: Barry Song Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- mm/huge_memory.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index dd66c6ad5af1..09cf40357557 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3929,6 +3929,9 @@ static int __split_unmapped_folio(struct folio *folio= , int new_order, int folio_check_splittable(struct folio *folio, unsigned int new_order, enum split_type split_type) { + const bool is_anon =3D folio_test_anon(folio); + const bool is_swapcache =3D folio_test_swapcache(folio); + VM_WARN_ON_FOLIO(!folio_test_locked(folio), folio); /* * Folios that just got truncated cannot get split. Signal to the @@ -3937,11 +3940,11 @@ int folio_check_splittable(struct folio *folio, uns= igned int new_order, * TODO: this will also currently refuse folios without a mapping in the * swapcache (shmem or to-be-anon folios). */ - if (!folio->mapping && !folio_test_anon(folio)) + if (!folio->mapping && !is_anon) return -EBUSY; =20 /* order-1 is not supported for anonymous THP. */ - if (folio_test_anon(folio) && new_order =3D=3D 1) + if (is_anon && new_order =3D=3D 1) return -EINVAL; =20 /* @@ -3952,7 +3955,7 @@ int folio_check_splittable(struct folio *folio, unsig= ned int new_order, * swapcache folio split. Only uniform split to order-0 can be used * here. */ - if ((split_type =3D=3D SPLIT_TYPE_NON_UNIFORM || new_order) && folio_test= _swapcache(folio)) + if ((split_type =3D=3D SPLIT_TYPE_NON_UNIFORM || new_order) && is_swapcac= he) return -EINVAL; =20 if (is_huge_zero_folio(folio)) @@ -3961,6 +3964,15 @@ int folio_check_splittable(struct folio *folio, unsi= gned int new_order, if (folio_test_writeback(folio)) return -EBUSY; =20 + /* + * A non-anon swapcache folio that still has a mapping can only be a + * shmem folio under SWAP IO, it's removed from either swap cache or + * shmem mapping afterward. There is little benefit in splitting them + * hence reject it here up front before touching anything. + */ + if (!is_anon && is_swapcache && folio->mapping) + return -EBUSY; + return 0; } =20 @@ -4019,14 +4031,8 @@ static int __folio_freeze_and_split_unmapped(struct = folio *folio, unsigned int n } } =20 - if (folio_test_swapcache(folio)) { - if (mapping) { - VM_WARN_ON_ONCE_FOLIO(mapping, folio); - return -EINVAL; - } - + if (folio_test_swapcache(folio)) ci =3D swap_cluster_get_and_lock(folio); - } =20 /* lock lru list/PageCompound, ref frozen by page_ref_freeze */ if (do_lru) --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 E5990521204 for ; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=dyGSwjDzqcCXTQu+iIn9KrpuzLCjpEsM8Lxgox8bPJcuyNyk6AAp7CNBLOU2X0U4AIFv7Y/HSPAI78OEU9dIAPBDQHaCwj46T9cjXJM9NZpYEw2LiDuODzHOQWCLp8ldmle6ri5l4zS8TZOyXUL1jiceZQUgmg1i/6kpcHiH3f4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=eGSL2SBpTQ+mXwcDKZqFvaInRtYaF2PnawvlGiffnQk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I4Oq4JUzoSJdnP6hKcK6HAOTOSAdpwvbJShelJsCh93V0Tdkl/ObvSIKq7id69v0MKRozRiTR6zOnNxP3AGNViCzcrC2IW2SdUArS5rCqqArsC0eZ8WsutU8YNpLk6sDb8R+mgGUU7fO4eY7UKfhE1zL67KhX+BMTbHq22/P3hA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JHFXxPay; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JHFXxPay" Received: by smtp.kernel.org (Postfix) with ESMTPS id BA7BAC2BCFF; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804735; bh=eGSL2SBpTQ+mXwcDKZqFvaInRtYaF2PnawvlGiffnQk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=JHFXxPayLPq4e6Jy7OXAMznpP8/Io2Oo2Ou6J1Dns691iZbZIf10NZolXZkiN98Ln G+8Bbg2omnVGlp6y9MPYgfoaRxqyrquoeIBSGSrNVp9pivjC3+x0+ZGTOOg7Mae7lX 4Ah/Klg5xDsA6FBFNX00j8MqrbO5J9JUjiMeeM9UxhoqyUCTMMhbLMV8cXCnGHE3kd 0nqKCNQWAAR7Juflq6H41XDpz3pwp7dEOhCUypdXB+ol+4uhoOFVvYTREGT4VTOxMW dhgn4Kw12h0tkY1Xv9IoOWu5NZmL8Ubg6WbWUYhPk7z+g44KvhiZRFcDbFaXelQZZw bz4paS0w9IgGQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3402C79FA7; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:07 +0800 Subject: [PATCH v4 03/17] mm/huge_memory: invert folio_ref_freeze() check to reduce indentation 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: <20260908-swap-thp-cleanup-v4-3-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=8106; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=Dd/0CiPPVaIxMOajFfYFtI4g6AN9xcx8WFIdQNPC7lg=; b=wRErGQ6z/S+OZ3gj8UV9CJMQjToRT30bM+DHIGkUGcyhPfnLrZXExisnXAbEEu/0RTBzfoXMR u0T37t6GIugBY4RHht2ejU9+Kvm049YwWv0iFkXMFWfws2FdNHf0qEj X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song Invert the folio_ref_freeze() success check in __folio_freeze_and_split_unmapped() to return early on failure, which removes one level of indentation from the entire success path. This is a pure refactoring with no functional change. It prepares the function to be split into separate helpers for anonymous and file-backed folios in a later patch. Reviewed-by: Zi Yan Reviewed-by: Barry Song Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- mm/huge_memory.c | 185 +++++++++++++++++++++++++++------------------------= ---- 1 file changed, 91 insertions(+), 94 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 09cf40357557..ad45b86819fd 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3991,126 +3991,123 @@ static int __folio_freeze_and_split_unmapped(stru= ct folio *folio, unsigned int n pgoff_t end, int *nr_shmem_dropped) { struct folio *end_folio =3D folio_next(folio); + struct swap_cluster_info *ci =3D NULL; struct folio *new_folio, *next; int old_order =3D folio_order(folio); + struct lruvec *lruvec; int ret =3D 0; =20 VM_WARN_ON_ONCE(!mapping && end); =20 - if (folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) { - struct swap_cluster_info *ci =3D NULL; - struct lruvec *lruvec; + if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) + return -EAGAIN; =20 - /* Take off the deferred split queue while frozen and memcg set */ - folio_unqueue_deferred_split(folio); + /* Take off the deferred split queue while frozen and memcg set */ + folio_unqueue_deferred_split(folio); =20 - /* - * deferred_split_scan() takes the folio off the queue before it - * splits it, so the unqueue above finds an empty list and - * leaves PG_partially_mapped set. - * Clear it here: the flag does not survive the split. - */ - if (folio_test_partially_mapped(folio)) { - folio_clear_partially_mapped(folio); - mod_mthp_stat(old_order, - MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1); - } + /* + * deferred_split_scan() takes the folio off the queue before it + * splits it, so the unqueue above finds an empty list and + * leaves PG_partially_mapped set. + * Clear it here: the flag does not survive the split. + */ + if (folio_test_partially_mapped(folio)) { + folio_clear_partially_mapped(folio); + mod_mthp_stat(old_order, + MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1); + } =20 - if (mapping) { - int nr =3D folio_nr_pages(folio); - - if (folio_test_pmd_mappable(folio) && - new_order < HPAGE_PMD_ORDER) { - if (folio_test_swapbacked(folio)) { - lruvec_stat_mod_folio(folio, - NR_SHMEM_THPS, -nr); - } else { - lruvec_stat_mod_folio(folio, - NR_FILE_THPS, -nr); - } + if (mapping) { + int nr =3D folio_nr_pages(folio); + + if (folio_test_pmd_mappable(folio) && + new_order < HPAGE_PMD_ORDER) { + if (folio_test_swapbacked(folio)) { + lruvec_stat_mod_folio(folio, + NR_SHMEM_THPS, -nr); + } else { + lruvec_stat_mod_folio(folio, + NR_FILE_THPS, -nr); } } + } =20 - if (folio_test_swapcache(folio)) - ci =3D swap_cluster_get_and_lock(folio); - - /* lock lru list/PageCompound, ref frozen by page_ref_freeze */ - if (do_lru) - lruvec =3D folio_lruvec_lock(folio); + if (folio_test_swapcache(folio)) + ci =3D swap_cluster_get_and_lock(folio); =20 - ret =3D __split_unmapped_folio(folio, new_order, split_at, xas, - mapping, split_type); + /* lock lru list/PageCompound, ref frozen by page_ref_freeze */ + if (do_lru) + lruvec =3D folio_lruvec_lock(folio); =20 - /* - * Unfreeze after-split folios and put them back to the right - * list. @folio should be kept frozon until page cache - * entries are updated with all the other after-split folios - * to prevent others seeing stale page cache entries. - * As a result, new_folio starts from the next folio of - * @folio. - */ - for (new_folio =3D folio_next(folio); new_folio !=3D end_folio; - new_folio =3D next) { - unsigned long nr_pages =3D folio_nr_pages(new_folio); + ret =3D __split_unmapped_folio(folio, new_order, split_at, xas, + mapping, split_type); =20 - next =3D folio_next(new_folio); + /* + * Unfreeze after-split folios and put them back to the right + * list. @folio should be kept frozon until page cache + * entries are updated with all the other after-split folios + * to prevent others seeing stale page cache entries. + * As a result, new_folio starts from the next folio of + * @folio. + */ + for (new_folio =3D folio_next(folio); new_folio !=3D end_folio; + new_folio =3D next) { + unsigned long nr_pages =3D folio_nr_pages(new_folio); =20 - zone_device_private_split_cb(folio, new_folio); + next =3D folio_next(new_folio); =20 - folio_ref_unfreeze(new_folio, - folio_cache_ref_count(new_folio) + 1); + zone_device_private_split_cb(folio, new_folio); =20 - if (do_lru) - lru_add_split_folio(folio, new_folio, lruvec, list); + folio_ref_unfreeze(new_folio, + folio_cache_ref_count(new_folio) + 1); =20 - /* - * Anonymous folio with swap cache. - * NOTE: shmem in swap cache is not supported yet. - */ - if (ci) { - __swap_cache_replace_folio(ci, folio, new_folio); - continue; - } + if (do_lru) + lru_add_split_folio(folio, new_folio, lruvec, list); =20 - /* Anonymous folio without swap cache */ - if (!mapping) - continue; + /* + * Anonymous folio with swap cache. + * NOTE: shmem in swap cache is not supported yet. + */ + if (ci) { + __swap_cache_replace_folio(ci, folio, new_folio); + continue; + } =20 - /* Add the new folio to the page cache. */ - if (new_folio->index < end) { - __xa_store(&mapping->i_pages, new_folio->index, - new_folio, 0); - continue; - } + /* Anonymous folio without swap cache */ + if (!mapping) + continue; =20 - VM_WARN_ON_ONCE(!nr_shmem_dropped); - /* Drop folio beyond EOF: ->index >=3D end */ - if (shmem_mapping(mapping) && nr_shmem_dropped) - *nr_shmem_dropped +=3D nr_pages; - else if (folio_test_clear_dirty(new_folio)) - folio_account_cleaned( - new_folio, inode_to_wb(mapping->host)); - __filemap_remove_folio(new_folio, NULL); - folio_put_refs(new_folio, nr_pages); + /* Add the new folio to the page cache. */ + if (new_folio->index < end) { + __xa_store(&mapping->i_pages, new_folio->index, + new_folio, 0); + continue; } =20 - zone_device_private_split_cb(folio, NULL); - /* - * Unfreeze @folio only after all page cache entries, which - * used to point to it, have been updated with new folios. - * Otherwise, a parallel folio_try_get() can grab @folio - * and its caller can see stale page cache entries. - */ - folio_ref_unfreeze(folio, folio_cache_ref_count(folio) + 1); + VM_WARN_ON_ONCE(!nr_shmem_dropped); + /* Drop folio beyond EOF: ->index >=3D end */ + if (shmem_mapping(mapping) && nr_shmem_dropped) + *nr_shmem_dropped +=3D nr_pages; + else if (folio_test_clear_dirty(new_folio)) + folio_account_cleaned(new_folio, + inode_to_wb(mapping->host)); + __filemap_remove_folio(new_folio, NULL); + folio_put_refs(new_folio, nr_pages); + } =20 - if (do_lru) - lruvec_unlock(lruvec); + zone_device_private_split_cb(folio, NULL); + /* + * Unfreeze @folio only after all page cache entries, which + * used to point to it, have been updated with new folios. + * Otherwise, a parallel folio_try_get() can grab @folio + * and its caller can see stale page cache entries. + */ + folio_ref_unfreeze(folio, folio_cache_ref_count(folio) + 1); =20 - if (ci) - swap_cluster_unlock(ci); - } else { - return -EAGAIN; - } + if (do_lru) + lruvec_unlock(lruvec); + if (ci) + swap_cluster_unlock(ci); =20 return ret; } --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2CD57521237 for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=BR8UN+crn2rMbpN6oDZsptC59Sag5T9yBbNwJz81g1oI3QDT+1RLOgSROq1oyLTzyh88My1712XuJeTLTlUWzIWeOVkvI56aF0W7O6hlLQyZrTH7lsQOUOijNwbw0oUTdbNTdbrTWMn1wrZJrpdLAj5JQsWAc7QIjtA0zsRpaiU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=UQxE9U8zUuQpP1iKLbROwSQIKo79F5tPHz6aqRL825o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GZ4Hzj/RD0rkmtNy4ivYF0o0Qk9HTSB7Jd2WFltAxVqaptqPUykdKhQ8vNUDALMiGgUiyfAqvbCLMadQSjox45F+9mI2D1Rwsc6Bza9Guo542RGpnVvqBfvjubEZZtCY9lpKW4ADyYwqVh3gPmQwo/d9xKEgf9XuRRjXWqqgrbc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hc5Qakwd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hc5Qakwd" Received: by smtp.kernel.org (Postfix) with ESMTPS id E0DD7C2BD00; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804735; bh=UQxE9U8zUuQpP1iKLbROwSQIKo79F5tPHz6aqRL825o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=hc5QakwdjZra0foEV0Kv/LTqxuLX6pLXe7wqKIzB5CE2mA83462k4+z18+u0abrOT B7TLEOB71hg30fgKjFjto2j0Azc9aRom4YrUcW/CAR5ZsOc+pYVuGyQRLSzieUEhl1 P9HLwDxGLfpva1/laQEbATnw5zxI84fdCPN10AwE1qI1QtYIrI7VUwcBSUgjpkyXvd gppnSioCWjAmGGfMcbflWAG6BZrNvG7w9t82KVPdIL1NWt8GpkPbyzVf/k0Tah+gP5 /erVBTeOSqFgW+R1CZTlaNNRBVRAgLTMqp0Yy6yaBQLOMWeImGDR46VcY7+g2bh+zt GdZEIg9McqrFw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C692BC79F9F; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:08 +0800 Subject: [PATCH v4 04/17] mm/huge_memory: split the routine for splitting anon and file folio 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: <20260908-swap-thp-cleanup-v4-4-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=8272; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=F8dPsP3fFvpOvuos1eYuyIIw+I21YsBNU7NmRi/afk0=; b=ZyKgqL3xLR1pnD3HAXBLQcjz38JCrnSMlJMXoKMqJVXy7WduKuWGyOhW8e/nqm+yS5Or0WtoP D/nK/iIkQbqDlD9U9nrS3zyhnpi/+T1ZsuFxm2yA7FdHDqXLT4uko18 X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song No functional change intended. Before adding more logic, split __folio_freeze_and_split_unmapped() into an anon and a file variant so each path can evolve independently. The two paths shared little beyond the folio freeze call, the LRU locking, and the unfreeze skeleton, but differed in all other per-folio bookkeeping and routines. While splitting, some cleanups become easy to apply, and helped drop a few now-redundant checks. The zone_device_private_split_cb() calls are only kept in the anon variant, as device private folios can only back anonymous memory, and add a VM_WARN_ON_ONCE_FOLIO() at the entry of the file variant. Acked-by: David Hildenbrand (Arm) Reviewed-by: Zi Yan Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) --- mm/huge_memory.c | 123 +++++++++++++++++++++++++++++++++++----------------= ---- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index ad45b86819fd..0e28a3e66b67 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3984,11 +3984,9 @@ static unsigned int folio_cache_ref_count(const stru= ct folio *folio) return folio_nr_pages(folio); } =20 -static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned= int new_order, - struct page *split_at, struct xa_state *xas, - struct address_space *mapping, bool do_lru, - struct list_head *list, enum split_type split_type, - pgoff_t end, int *nr_shmem_dropped) +static int __folio_freeze_split_anon(struct folio *folio, + unsigned int new_order, struct page *split_at, bool do_lru, + struct list_head *list, enum split_type split_type) { struct folio *end_folio =3D folio_next(folio); struct swap_cluster_info *ci =3D NULL; @@ -3997,8 +3995,6 @@ static int __folio_freeze_and_split_unmapped(struct f= olio *folio, unsigned int n struct lruvec *lruvec; int ret =3D 0; =20 - VM_WARN_ON_ONCE(!mapping && end); - if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) return -EAGAIN; =20 @@ -4017,24 +4013,75 @@ static int __folio_freeze_and_split_unmapped(struct= folio *folio, unsigned int n MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1); } =20 - if (mapping) { + if (folio_test_swapcache(folio)) + ci =3D swap_cluster_get_and_lock(folio); + + if (do_lru) + lruvec =3D folio_lruvec_lock(folio); + + ret =3D __split_unmapped_folio(folio, new_order, split_at, NULL, + NULL, split_type); + + /* + * Unfreeze the after-split folios and put them back to the right + * place. Keep the head @folio frozen until the end: sub entries + * in swap cache must be updated first, so a concurrent + * swap_cache_get_folio() cannot return the head folio for a sub + * entry (folio_try_get() will fail on the head @folio until unfreeze). + */ + for (new_folio =3D folio_next(folio); new_folio !=3D end_folio; + new_folio =3D next) { + next =3D folio_next(new_folio); + zone_device_private_split_cb(folio, new_folio); + folio_ref_unfreeze(new_folio, + folio_cache_ref_count(new_folio) + 1); + if (do_lru) + lru_add_split_folio(folio, new_folio, lruvec, list); + if (ci) + __swap_cache_replace_folio(ci, folio, new_folio); + } + + zone_device_private_split_cb(folio, NULL); + folio_ref_unfreeze(folio, folio_cache_ref_count(folio) + 1); + + if (do_lru) + lruvec_unlock(lruvec); + if (ci) + swap_cluster_unlock(ci); + + return ret; +} + +static int __folio_freeze_split_file(struct folio *folio, + unsigned int new_order, struct page *split_at, + struct xa_state *xas, struct address_space *mapping, + bool do_lru, struct list_head *list, + enum split_type split_type, pgoff_t end, int *nr_shmem_dropped) +{ + struct folio *end_folio =3D folio_next(folio); + struct folio *new_folio, *next; + struct lruvec *lruvec; + int ret; + + /* Currently device private folios can only back anonymous memory. */ + VM_WARN_ON_ONCE_FOLIO(folio_is_device_private(folio), folio); + + if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) + return -EAGAIN; + + if (folio_test_pmd_mappable(folio) && + new_order < HPAGE_PMD_ORDER) { int nr =3D folio_nr_pages(folio); =20 - if (folio_test_pmd_mappable(folio) && - new_order < HPAGE_PMD_ORDER) { - if (folio_test_swapbacked(folio)) { - lruvec_stat_mod_folio(folio, - NR_SHMEM_THPS, -nr); - } else { - lruvec_stat_mod_folio(folio, - NR_FILE_THPS, -nr); - } + if (folio_test_swapbacked(folio)) { + lruvec_stat_mod_folio(folio, + NR_SHMEM_THPS, -nr); + } else { + lruvec_stat_mod_folio(folio, + NR_FILE_THPS, -nr); } } =20 - if (folio_test_swapcache(folio)) - ci =3D swap_cluster_get_and_lock(folio); - /* lock lru list/PageCompound, ref frozen by page_ref_freeze */ if (do_lru) lruvec =3D folio_lruvec_lock(folio); @@ -4044,7 +4091,7 @@ static int __folio_freeze_and_split_unmapped(struct f= olio *folio, unsigned int n =20 /* * Unfreeze after-split folios and put them back to the right - * list. @folio should be kept frozon until page cache + * list. @folio should be kept frozen until page cache * entries are updated with all the other after-split folios * to prevent others seeing stale page cache entries. * As a result, new_folio starts from the next folio of @@ -4054,29 +4101,15 @@ static int __folio_freeze_and_split_unmapped(struct= folio *folio, unsigned int n new_folio =3D next) { unsigned long nr_pages =3D folio_nr_pages(new_folio); =20 + /* compute next before the folio can be freed below */ next =3D folio_next(new_folio); =20 - zone_device_private_split_cb(folio, new_folio); - folio_ref_unfreeze(new_folio, folio_cache_ref_count(new_folio) + 1); =20 if (do_lru) lru_add_split_folio(folio, new_folio, lruvec, list); =20 - /* - * Anonymous folio with swap cache. - * NOTE: shmem in swap cache is not supported yet. - */ - if (ci) { - __swap_cache_replace_folio(ci, folio, new_folio); - continue; - } - - /* Anonymous folio without swap cache */ - if (!mapping) - continue; - /* Add the new folio to the page cache. */ if (new_folio->index < end) { __xa_store(&mapping->i_pages, new_folio->index, @@ -4095,7 +4128,6 @@ static int __folio_freeze_and_split_unmapped(struct f= olio *folio, unsigned int n folio_put_refs(new_folio, nr_pages); } =20 - zone_device_private_split_cb(folio, NULL); /* * Unfreeze @folio only after all page cache entries, which * used to point to it, have been updated with new folios. @@ -4106,8 +4138,6 @@ static int __folio_freeze_and_split_unmapped(struct f= olio *folio, unsigned int n =20 if (do_lru) lruvec_unlock(lruvec); - if (ci) - swap_cluster_unlock(ci); =20 return ret; } @@ -4250,7 +4280,10 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, =20 /* block interrupt reentry in xa_lock and spinlock */ local_irq_disable(); - if (mapping) { + if (is_anon) { + ret =3D __folio_freeze_split_anon(folio, new_order, split_at, + true, list, split_type); + } else { /* * Check if the folio is present in page cache. * We assume all tail are present too, if folio is there. @@ -4261,10 +4294,11 @@ static int __folio_split(struct folio *folio, unsig= ned int new_order, ret =3D -EAGAIN; goto fail; } + ret =3D __folio_freeze_split_file(folio, new_order, split_at, &xas, mapp= ing, + true, list, split_type, end, + &nr_shmem_dropped); } =20 - ret =3D __folio_freeze_and_split_unmapped(folio, new_order, split_at, &xa= s, mapping, - true, list, split_type, end, &nr_shmem_dropped); fail: if (mapping) xas_unlock(&xas); @@ -4364,9 +4398,8 @@ int folio_split_unmapped(struct folio *folio, unsigne= d int new_order) return -EAGAIN; =20 local_irq_disable(); - ret =3D __folio_freeze_and_split_unmapped(folio, new_order, &folio->page,= NULL, - NULL, false, NULL, SPLIT_TYPE_UNIFORM, - 0, NULL); + ret =3D __folio_freeze_split_anon(folio, new_order, &folio->page, + false, NULL, SPLIT_TYPE_UNIFORM); local_irq_enable(); return ret; } --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 39EBB5221C1 for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=gCEsKiC0R2nh6UbeLOZCdXhbyQLPxTj51MiHs52mib5ddIrP6MQB7iE8IufzzrZuE3/0C0Unj3NvBrYNROiAmh8211rNrE3ltrUzzKqRdLflxPdpOo8nYu+mCv2I1dc8On5kkPCipnhpG7Ar0BbxSuKXCc2sS9rwFssvySDYEeo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=K1e7htnY/isOkcfxTMCbkRGPSSouWnsnU2rQFgEN/qU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UDBDgL+3t+/2vlh6A0gly7ucTd7NjMEkTOYXNMzVnaPHhtxeAAIgBcRHa99IZ85ZZ2k2m0WmW9s2qdaM7NLQUGiq1PjayPi7HC4jyCqpWDRtnTmf5kAQJqlgJ8YOT9972PziqGo6XDseyIOQm5uk9ZzYrCjkkO3Ms/dNbAAy2C0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=s6hVUIqA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="s6hVUIqA" Received: by smtp.kernel.org (Postfix) with ESMTPS id 0DC61C2BCFC; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=K1e7htnY/isOkcfxTMCbkRGPSSouWnsnU2rQFgEN/qU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=s6hVUIqAPeW2jZVJcnMOvpUUgscI0LQaBVFkzOLulANDu+kSwpjA0cqUi44FjLaV4 cUzcsW4rZP1echBI66oKMjNkl3eiXzy/f+jPaLSVpj917wBKWCaZGguUdQuMtFdgjD paKH2bVdtiUiN78yHQHWH4l/8/AMcvEH6v4fBz9uMiaB8+TiYadYdFmB3U+USnjnfN 3M0X5CYX66MX5F7r6hSkJ+zoitwD6df2ck+6zUQAHzPG5XdhYRj73P3GgVKssi+aAU A3tNcThq5NeSsbtTBCjkD0uujHy3levCPE0tF+2OFyDPiXU4VTwY5r45aXlbjiK1B7 oq8Manm2eDpAg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB01BC79F99; Mon, 7 Sep 2026 18:12:15 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:09 +0800 Subject: [PATCH v4 05/17] mm/huge_memory: rename __split_unmapped_folio() to __split_frozen_folio() 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: <20260908-swap-thp-cleanup-v4-5-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=4226; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=8jugUiqqC1QVhhoobTnFHgSZS/cT933y7hBRNZpc0W4=; b=0nvoYfPHFfpr/NPg/dullsm9XbVnEHETJwtfP8R+e+MswKQP8zAnkn2TrQI0n+/7jcXbHPQMp 0dDjzQOTJc2D1iwFUfRXZfYsm5X47NorICKmmeWDkl/vu9jVT/3el2C X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song The helper splits a folio whose refcount is frozen: the frozen refcount is the state it relies on, while unmapping is arranged by the caller beforehand. The old name caused confusion and people may try to call the helper on non-frozen folios. Also add a VM_WARN_ON_ONCE_FOLIO(folio_mapped(folio)) to self document that frozen implies unmapped. Suggested-by: Zi Yan Reviewed-by: Zi Yan Reviewed-by: Yeoreum Yun Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song Acked-by: David Hildenbrand (Arm) --- mm/huge_memory.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 0e28a3e66b67..80291fac78e2 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3806,8 +3806,8 @@ static void __split_folio_to_order(struct folio *foli= o, int old_order, } =20 /** - * __split_unmapped_folio() - splits an unmapped @folio to lower order fol= ios in - * two ways: uniform split or non-uniform split. + * __split_frozen_folio() - splits a frozen @folio to lower order folios + * in two ways: uniform split or non-uniform split. * @folio: the to-be-split folio * @new_order: the smallest order of the after split folios (since buddy * allocator like split generates folios with orders from @fol= io's @@ -3846,7 +3846,7 @@ static void __split_folio_to_order(struct folio *foli= o, int old_order, * Return: 0 - successful, <0 - failed (if -ENOMEM is returned, @folio mig= ht be * split but not to @new_order, the caller needs to check) */ -static int __split_unmapped_folio(struct folio *folio, int new_order, +static int __split_frozen_folio(struct folio *folio, int new_order, struct page *split_at, struct xa_state *xas, struct address_space *mapping, enum split_type split_type) { @@ -3856,6 +3856,9 @@ static int __split_unmapped_folio(struct folio *folio= , int new_order, struct folio *old_folio =3D folio; int split_order; =20 + /* Frozen implies unmapped, callers unmap before splitting. */ + VM_WARN_ON_ONCE_FOLIO(folio_mapped(folio), folio); + /* * split to new_order one order at a time. For uniform split, * folio is split to new_order directly. @@ -4019,8 +4022,8 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, if (do_lru) lruvec =3D folio_lruvec_lock(folio); =20 - ret =3D __split_unmapped_folio(folio, new_order, split_at, NULL, - NULL, split_type); + ret =3D __split_frozen_folio(folio, new_order, split_at, NULL, + NULL, split_type); =20 /* * Unfreeze the after-split folios and put them back to the right @@ -4086,8 +4089,8 @@ static int __folio_freeze_split_file(struct folio *fo= lio, if (do_lru) lruvec =3D folio_lruvec_lock(folio); =20 - ret =3D __split_unmapped_folio(folio, new_order, split_at, xas, - mapping, split_type); + ret =3D __split_frozen_folio(folio, new_order, split_at, xas, + mapping, split_type); =20 /* * Unfreeze after-split folios and put them back to the right @@ -4151,9 +4154,9 @@ static int __folio_freeze_split_file(struct folio *fo= lio, * @list: after-split folios will be put on it if non NULL * @split_type: perform uniform split or not (non-uniform split) * - * It calls __split_unmapped_folio() to perform uniform and non-uniform sp= lit. + * It calls __split_frozen_folio() to perform uniform and non-uniform spli= t. * It is in charge of checking whether the split is supported or not and - * preparing @folio for __split_unmapped_folio(). + * preparing @folio for __split_frozen_folio(). * * After splitting, the after-split folio containing @lock_at remains lock= ed * and others are unlocked: @@ -4256,7 +4259,7 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, i_mmap_lock_read(mapping); =20 /* - *__split_unmapped_folio() may need to trim off pages beyond + * __split_frozen_folio() may need to trim off pages beyond * EOF: but on 32-bit, i_size_read() takes an irq-unsafe * seqlock, which cannot be nested inside the page tree lock. * So note end now: i_size itself may be changed at any moment, --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 696065221D9 for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=HpJMTi1DC+hZIG5TrBcvpQgR0UmanthSyCy1lvA3RbCkn5oWxU6TtXrkj9zgKC89p9sxsdPOFEy2VefmPtjT6rlgPbeEqoFvT8erK9tmZMpJxbS3cBeqnnjttnaIg6eXJ8Tq6WGGXB8krmsNm94/rpwvqJpE1o20jIaLA3v8O6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=Kp+saGqgfVHTFPckrEozr1au3f5YEP3Z32PBrb7701c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IxcFNycnN2pVS+NRZw2Mk9FVUnedGjJTx8eV/Wu4X/4EC5Oi3N6IKGQgMxZx2JdCTY4IHDMMh62tS6xBkXXweX2l7WGjJAs5Gfv7WjPjY4LX/bnc2r2XjLc1vSVfYBIJ6Ij/3TcWratJJ8cswZW8hWGk2TfjbMh8Rfq6loBrs+M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YdrkK4FL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YdrkK4FL" Received: by smtp.kernel.org (Postfix) with ESMTPS id 2C5FAC2BCF4; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=Kp+saGqgfVHTFPckrEozr1au3f5YEP3Z32PBrb7701c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=YdrkK4FLFduabVFNi0Q0otWarEOgfkgXLWJURMRHQiKIDrnrcEQtl1vNFiZrVjiMp xcaLkU5uK+jAX9UsHEs2lY2ciexXVitmSn+eLL8wgHTJXyBh0MN32YGsj9j5EFLCNF eJxMRtJ6XTrdvSMlUzBorTBao1iECziRJIQZMh2WS6GKgzpTKNloFuL5ZG6TLtpiJt yPFMi/zAZ+CwmK4sll7MxL35yj+wHgJedm4OXRJrDIm8fhYz8+CvunXCSQQkqljESR JwVB0IKgH333C4HNS378P1EwExehVQRDnnK4doIiiICwLTwtT+oGdtzA3GnzJkQCs6 QOnpBRImdlvHQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16331C79FA0; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:10 +0800 Subject: [PATCH v4 06/17] mm/huge_memory: consolidate irq and locking for folio split 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: <20260908-swap-thp-cleanup-v4-6-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=4844; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=53UDy2nNH5r0qRCm1hHT5ySIpLRkBQgkPRBtLrEgdWQ=; b=IlEriGK3IEX+/Zbm5O2sbGuRjSFvDExSvyRDZiljCnBM5NTtwFZETi85va12V9lj2yDsmb+Qg 3jBwUtZzf9VA8ohnJylwlI3k96DzdI6N0Vfbwtq0BfrlB8osxYQto1q X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song Let each split helper handle its own locking instead of relying on the caller, so both helpers manage their own irq and locking state. This lets __folio_split() drop its local irq handling and fail label, preparing for further cleanup. The file path now uses xas_lock_irq() instead of local_irq_disable() with xas_lock(). The two are equivalent on non-RT, and TRANSPARENT_HUGEPAGE cannot be enabled on RT anyway. This conversion also buys consistency: every other place in mm/ that freezes a folio while it is still reachable through the page cache already takes the lock this way. This was actually the last plain xas_lock() on mapping->i_pages left in mm. If we are going to support RT, spinning on frozen folio refs could be a problem, but it already exists in many places and should be fixed generically. The anon helper keeps a single local_irq_disable() as before, because it has to cover several plain spinlocks at once. The dropped xas_reset() was a no-op as the xa_state is not walked before the xas_load() under the lock. Reviewed-by: Zi Yan Reviewed-by: Kiryl Shutsemau (Meta) Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Acked-by: David Hildenbrand (Arm) --- mm/huge_memory.c | 58 ++++++++++++++++++++++++++--------------------------= ---- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 80291fac78e2..4ddef481cfdc 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3998,8 +3998,12 @@ static int __folio_freeze_split_anon(struct folio *f= olio, struct lruvec *lruvec; int ret =3D 0; =20 - if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) + local_irq_disable(); + + if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) { + local_irq_enable(); return -EAGAIN; + } =20 /* Take off the deferred split queue while frozen and memcg set */ folio_unqueue_deferred_split(folio); @@ -4051,6 +4055,7 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, lruvec_unlock(lruvec); if (ci) swap_cluster_unlock(ci); + local_irq_enable(); =20 return ret; } @@ -4069,8 +4074,21 @@ static int __folio_freeze_split_file(struct folio *f= olio, /* Currently device private folios can only back anonymous memory. */ VM_WARN_ON_ONCE_FOLIO(folio_is_device_private(folio), folio); =20 - if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) - return -EAGAIN; + xas_lock_irq(xas); + + /* + * Check if the folio is present in page cache. + * We assume all tail are present too, if folio is there. + */ + if (xas_load(xas) !=3D folio) { + ret =3D -EAGAIN; + goto fail; + } + + if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) { + ret =3D -EAGAIN; + goto fail; + } =20 if (folio_test_pmd_mappable(folio) && new_order < HPAGE_PMD_ORDER) { @@ -4142,6 +4160,8 @@ static int __folio_freeze_split_file(struct folio *fo= lio, if (do_lru) lruvec_unlock(lruvec); =20 +fail: + xas_unlock_irq(xas); return ret; } =20 @@ -4281,32 +4301,13 @@ static int __folio_split(struct folio *folio, unsig= ned int new_order, =20 unmap_folio(folio); =20 - /* block interrupt reentry in xa_lock and spinlock */ - local_irq_disable(); - if (is_anon) { + if (is_anon) ret =3D __folio_freeze_split_anon(folio, new_order, split_at, true, list, split_type); - } else { - /* - * Check if the folio is present in page cache. - * We assume all tail are present too, if folio is there. - */ - xas_lock(&xas); - xas_reset(&xas); - if (xas_load(&xas) !=3D folio) { - ret =3D -EAGAIN; - goto fail; - } + else ret =3D __folio_freeze_split_file(folio, new_order, split_at, &xas, mapp= ing, true, list, split_type, end, &nr_shmem_dropped); - } - -fail: - if (mapping) - xas_unlock(&xas); - - local_irq_enable(); =20 if (nr_shmem_dropped) shmem_uncharge(mapping->host, nr_shmem_dropped); @@ -4390,8 +4391,6 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, */ int folio_split_unmapped(struct folio *folio, unsigned int new_order) { - int ret =3D 0; - VM_WARN_ON_ONCE_FOLIO(folio_mapped(folio), folio); VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio); @@ -4400,11 +4399,8 @@ int folio_split_unmapped(struct folio *folio, unsign= ed int new_order) if (folio_expected_ref_count(folio) !=3D folio_ref_count(folio) - 1) return -EAGAIN; =20 - local_irq_disable(); - ret =3D __folio_freeze_split_anon(folio, new_order, &folio->page, - false, NULL, SPLIT_TYPE_UNIFORM); - local_irq_enable(); - return ret; + return __folio_freeze_split_anon(folio, new_order, &folio->page, + false, NULL, SPLIT_TYPE_UNIFORM); } =20 /* --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6503F5221CE for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=OXDE2LxQozLlQe6emsA40Hpzzedn9HkhhPvsvbQPo+WQt5AJ1BCsRXl83RtvqFNPsfBuv3GlDQd/6XujV1NLxxo2p3GaJyyq8EQYsflE+MMX/FBBB4kIKbxe2Ny9Ul9zU5+CWtwRPJYBLp/YNeG0fucXCa7Ph4oiYJrYD0nTTGk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=CLYd+9rqSeAXmfOGfQPaGz7sWGXnVTIa35extcVMPFE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ijsurCJ3s/uRVWwkqsBtq9Ot5PzQ8nMuH6EY63TWC5bBrSt/A9VwsVJiM3SuDMZEai4f7Jn5hzknJjU8CQ78PzW2ndYbN3xm4vzOCst8aNqbBx1ndp1JzRbmXu+/+FDXYbXGMFBPzISXbpx+cgZk45dDuR5U/dZxI+8Kle8eG+E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=d2cp8bhu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="d2cp8bhu" Received: by smtp.kernel.org (Postfix) with ESMTPS id 45065C2BD01; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=CLYd+9rqSeAXmfOGfQPaGz7sWGXnVTIa35extcVMPFE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=d2cp8bhuIi5bmka0XQY7r0XQXITvpri9z+aHB3uMN+xpkGa/XLScdyEWthxrkA/oC q/3U/PE4WIgGO4PHK8z7HAyTCFsbqjMmu3K9AcYsVjxW4Dc8facI7MqtHV50CtJdT7 HWcI2gpgy+JJspGq2YOxC0LGmqWRgd7APaT259PN4BcvEia30bTSjFg+RmqT9NcK0J bbeedZ46IgwfvbKxxxTm+rRHUO55cn1WmizxHAGE7bvQ2fpHkHysLyHYAXCqUZ/PIk bVMZCwk5QdKt2p02K02wGASWBRwJu0cv2zwBBt8QK+/mjJ/l27vG+DkxIF3iRzVd/G oxbzvnW20TQvw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E779C79FAA; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:11 +0800 Subject: [PATCH v4 07/17] mm/huge_memory: move EOF trimming into the file split 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: <20260908-swap-thp-cleanup-v4-7-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=4120; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=ftkoXBBw3sFhzSDR+ufx8DUBg1yWFWLNTYmDd04kdNg=; b=RFswOgque5Oaf/nioeXAMNZpU66pzyHQFsZ9WV62FE/pJp+Fw3tJfkRgqdEIIJNhjSDhRF/JC TIybDy7ifI0CcoAujx5xjsR0GVdtPfi0zk4ewWdO81siP4Ei7RJhhf9 X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song Instead of receiving @end and @nr_shmem_dropped from the caller, the file split helper now computes the EOF boundary and trims pages beyond it itself, as this is only needed for file split. This drops the redundant parameter passing and sanity check. Reviewed-by: Zi Yan Acked-by: David Hildenbrand (Arm) Reviewed-by: Kiryl Shutsemau (Meta) Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song --- mm/huge_memory.c | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 4ddef481cfdc..47ccf2326cfe 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4064,16 +4064,29 @@ static int __folio_freeze_split_file(struct folio *= folio, unsigned int new_order, struct page *split_at, struct xa_state *xas, struct address_space *mapping, bool do_lru, struct list_head *list, - enum split_type split_type, pgoff_t end, int *nr_shmem_dropped) + enum split_type split_type) { struct folio *end_folio =3D folio_next(folio); struct folio *new_folio, *next; + int nr_shmem_dropped =3D 0; struct lruvec *lruvec; + pgoff_t end; int ret; =20 /* Currently device private folios can only back anonymous memory. */ VM_WARN_ON_ONCE_FOLIO(folio_is_device_private(folio), folio); =20 + /* + * The loop below may need to trim off pages beyond + * EOF: but on 32-bit, i_size_read() takes an irq-unsafe + * seqlock, which cannot be nested inside the page tree lock. + * So note end now: i_size itself may be changed at any moment, + * but folio lock is good enough to serialize the trimming. + */ + end =3D DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE); + if (shmem_mapping(mapping)) + end =3D shmem_fallocend(mapping->host, end); + xas_lock_irq(xas); =20 /* @@ -4138,10 +4151,9 @@ static int __folio_freeze_split_file(struct folio *f= olio, continue; } =20 - VM_WARN_ON_ONCE(!nr_shmem_dropped); /* Drop folio beyond EOF: ->index >=3D end */ - if (shmem_mapping(mapping) && nr_shmem_dropped) - *nr_shmem_dropped +=3D nr_pages; + if (shmem_mapping(mapping)) + nr_shmem_dropped +=3D nr_pages; else if (folio_test_clear_dirty(new_folio)) folio_account_cleaned(new_folio, inode_to_wb(mapping->host)); @@ -4162,6 +4174,8 @@ static int __folio_freeze_split_file(struct folio *fo= lio, =20 fail: xas_unlock_irq(xas); + if (nr_shmem_dropped) + shmem_uncharge(mapping->host, nr_shmem_dropped); return ret; } =20 @@ -4198,9 +4212,7 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, struct anon_vma *anon_vma =3D NULL; int old_order =3D folio_order(folio); struct folio *new_folio, *next; - int nr_shmem_dropped =3D 0; enum ttu_flags ttu_flags =3D 0; - pgoff_t end =3D 0; int ret; =20 VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); @@ -4277,17 +4289,6 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, =20 anon_vma =3D NULL; i_mmap_lock_read(mapping); - - /* - * __split_frozen_folio() may need to trim off pages beyond - * EOF: but on 32-bit, i_size_read() takes an irq-unsafe - * seqlock, which cannot be nested inside the page tree lock. - * So note end now: i_size itself may be changed at any moment, - * but folio lock is good enough to serialize the trimming. - */ - end =3D DIV_ROUND_UP(i_size_read(mapping->host), PAGE_SIZE); - if (shmem_mapping(mapping)) - end =3D shmem_fallocend(mapping->host, end); } =20 /* @@ -4306,11 +4307,7 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, true, list, split_type); else ret =3D __folio_freeze_split_file(folio, new_order, split_at, &xas, mapp= ing, - true, list, split_type, end, - &nr_shmem_dropped); - - if (nr_shmem_dropped) - shmem_uncharge(mapping->host, nr_shmem_dropped); + true, list, split_type); =20 if (!ret && is_anon && !folio_is_device_private(folio)) ttu_flags =3D TTU_USE_SHARED_ZEROPAGE; --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 76A805221DE for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=EP7uatcp0whegpPfgMpTE9018KhRRVRYSAAGG3hdzHa6g2CtETArehKxn2pp64kQeY12Ft81NLgmVo4L/9JLbZeUvyHLG/8Lu7h/bvSwk5CVOrq2r8pL5x9JQEc2Zh2fFf/0JsbC6S4YwaXdjdfvqA1uJArhjhQSIedJThOYbZQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=gfvvUIk/at6UwTcWzvjabNbGGeRmaBR57SeASlJRRMg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nJTTkOLW66unckgSZkWtMuSFs+Es4M8h/6sMpEj440zPP/6ePKzXryLoptgoMf1zsfjpic8jifhrAwHl28VLnx4Rg5Iin75hODCCJUnNSE5P9hS3I4iXW9LFwnV2yFPUGf+zg0OU+Yl6P0fbBY/8OwYJTBcm7r0Bonk+84OMwzA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IvVcwGnK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IvVcwGnK" Received: by smtp.kernel.org (Postfix) with ESMTPS id 59D2CC2BCC7; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=gfvvUIk/at6UwTcWzvjabNbGGeRmaBR57SeASlJRRMg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=IvVcwGnKAwohWi8jVjvQefQ+/Q6stoBvaLk4rXyFAb9hU6QoxU7FI/5+IWDJtIe48 2QjaPMOEZt5FbOJ0E6GVI5vB+Xay3X0okJuEcg0mBvOgCxNmMrdjVgofIaAZawJmob P8gUaJwUIITBFeiUJH/UNDx/3Lp40hO+hRLwjV7fR+J2trRTUyOPWF05p1C/KJJCcg j7u3W0s2SCBD5HoHx0QcbXtNMMm3DCQavULni9S2VPTAWwdQneBqZ/gaW/IXHjcBDT XHjn90qqarJDzH73FPzPWluIyn3BtAYNwUEbNMN48oA0ZDRz7BeGlpaZmbH2tSqzQW dcPw8XqnqhXsA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 437C6C79F99; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:12 +0800 Subject: [PATCH v4 08/17] mm/huge_memory: move unmap and remap into the split helpers 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: <20260908-swap-thp-cleanup-v4-8-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=3718; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=8rla4SJJrgTvzsnT4YVMcceDfbNPfTApzzjzHoKnAbE=; b=Z+m1XqtvYJ1c2EZdBoxY+IfPRPPJ6im1EtJt+NZENHRGR/MgPaiFx2721x3Qd59KKT4y/T4TP pODORevDxB8BeXsMdRBlxQxNitPBxqEtgb7p/VQel8vOSRKaTA2sS9D X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song To prepare for further cleanup, move the unmap/remap handling from __folio_split() into the split helpers. Only anon folios need to be remapped, so remap_page() is now only called for anon splits and the anon check in remap_page() is redundant and can be removed. Reviewed-by: Zi Yan Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) --- mm/huge_memory.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 47ccf2326cfe..7d7ce0726c19 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3640,9 +3640,6 @@ static void remap_page(struct folio *folio, unsigned = long nr, int flags) { int i =3D 0; =20 - /* If unmap_folio() uses try_to_migrate() on file, remove this check */ - if (!folio_test_anon(folio)) - return; for (;;) { remove_migration_ptes(folio, folio, TTU_RMAP_LOCKED | flags); i +=3D folio_nr_pages(folio); @@ -3995,14 +3992,21 @@ static int __folio_freeze_split_anon(struct folio *= folio, struct swap_cluster_info *ci =3D NULL; struct folio *new_folio, *next; int old_order =3D folio_order(folio); + enum ttu_flags ttu_flags =3D 0; struct lruvec *lruvec; + bool need_remap =3D false; int ret =3D 0; =20 + if (folio_mapped(folio)) { + need_remap =3D true; + unmap_folio(folio); + } + local_irq_disable(); =20 if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) { - local_irq_enable(); - return -EAGAIN; + ret =3D -EAGAIN; + goto out_no_split; } =20 /* Take off the deferred split queue while frozen and memcg set */ @@ -4055,7 +4059,13 @@ static int __folio_freeze_split_anon(struct folio *f= olio, lruvec_unlock(lruvec); if (ci) swap_cluster_unlock(ci); +out_no_split: local_irq_enable(); + if (need_remap) { + if (!ret && !folio_is_device_private(folio)) + ttu_flags =3D TTU_USE_SHARED_ZEROPAGE; + remap_page(folio, 1 << old_order, ttu_flags); + } =20 return ret; } @@ -4087,6 +4097,8 @@ static int __folio_freeze_split_file(struct folio *fo= lio, if (shmem_mapping(mapping)) end =3D shmem_fallocend(mapping->host, end); =20 + unmap_folio(folio); + xas_lock_irq(xas); =20 /* @@ -4171,8 +4183,11 @@ static int __folio_freeze_split_file(struct folio *f= olio, =20 if (do_lru) lruvec_unlock(lruvec); - fail: + /* + * If we want to use try_to_migrate() on file in unmap_folio, + * remember to add remap_page() and adapt it. + */ xas_unlock_irq(xas); if (nr_shmem_dropped) shmem_uncharge(mapping->host, nr_shmem_dropped); @@ -4212,7 +4227,6 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, struct anon_vma *anon_vma =3D NULL; int old_order =3D folio_order(folio); struct folio *new_folio, *next; - enum ttu_flags ttu_flags =3D 0; int ret; =20 VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio); @@ -4300,8 +4314,6 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, goto out_unlock; } =20 - unmap_folio(folio); - if (is_anon) ret =3D __folio_freeze_split_anon(folio, new_order, split_at, true, list, split_type); @@ -4309,11 +4321,6 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, ret =3D __folio_freeze_split_file(folio, new_order, split_at, &xas, mapp= ing, true, list, split_type); =20 - if (!ret && is_anon && !folio_is_device_private(folio)) - ttu_flags =3D TTU_USE_SHARED_ZEROPAGE; - - remap_page(folio, 1 << old_order, ttu_flags); - /* * Drop the mapping while the inode is still pinned. @folio stays * locked and present in the page cache until the loop below, so --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 C81225221EB for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=Y2goQsoYs1XHdEStVQj5v5dR2bdM/ZJw+5Led7MGnw9HIrSx0M/pcckB5ExRYJIpf/LVOEY2pBsMy8deydG37iAZTBi9eTx0KPn5jVkb2qZq3JuiwUig7g50eUSiHD3wL50nIbK2qeyA4ln/f0GB/kNPY3rHXZfAayQspWy3fJA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=lL6Vy66//mizHQ21EPUREXRDQG7iywmhU/CjbOBZ3LA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ELO3mTQ/fzmQ5UM/lfAQpR6iZdKSSYSn6goD/ra3v7JJVbP6qjiAUdZ+lakHoWCWTyqbQuV+TNFRbHRFoue8CV26FdelFTBupwpRaVGfg/9Ul+e1/Mq7aJDZ+VCqVy9MBjIbctYs5a3covpU0EDM4xlRpcrKmKEkpa03XRy+eGw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cxPLij5F; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cxPLij5F" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7F181C2BCFC; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=lL6Vy66//mizHQ21EPUREXRDQG7iywmhU/CjbOBZ3LA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=cxPLij5F446aQL09OYuirMUa+nQiRZcQ/QxbZzJGpgCSbtp4RDoBOqu1aLrYcwRhz oO8jDbZne2I8qKNoyEFtdldWhYkUY4cMNrI4Ij0ubpRkZyHLecY4LBOfQ8/DI1jqWh 1eF0jc5Brb7M7rfDNOyC4PmTP5Z2uaMONt37eF/tIYav/9KhKPwVLUdwPd1rxuSWMR A5XIWnjnyhqZhllZVX19ngDOhZbA+YZ45u8HZ3LGeWGe5eQGnAwWjVpFMyxdchi5r9 7MX3JpSopqiYr2YwQaIBbkmi1mwxOzaGB9OJfJZVh/wX+sb8NdV9TjGzhP0Mi4M4VX fQeXhy7IVyhMA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 617F1C79FA0; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:13 +0800 Subject: [PATCH v4 09/17] mm/huge_memory: rename remap_page() to remap_folio() 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: <20260908-swap-thp-cleanup-v4-9-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=3039; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=gXNchtrvyqO8Qb07cTlfilEi09UxJOToevoBYCcR4jc=; b=Syv9fnIAyYe2VN5RgwIMikCgkHNqhYmBPN/xGCM3eTwaLZlIRNd9uy6s1AzsmX9zn/y8DwVZk A2mcE7n3AAtBpqw2Qy7GfSYb+1AbfHZcCuqKMpXmpa2Hj8hdMzF5r+g X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song remap_page() now only has one caller, __folio_freeze_split_anon(), so rename it to remap_folio() to match the sibling helper unmap_folio(). Also add a VM_WARN_ON_FOLIO() documenting that remap_folio() is only ever called for anon folios: unmap_folio() currently leaves file folios unmapped after the split, so they need no remapping. Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) Reviewed-by: Zi Yan --- mm/huge_memory.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 7d7ce0726c19..c5279c0d0e59 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3551,7 +3551,7 @@ static void unmap_folio(struct folio *folio) /* * Anon pages need migration entries to preserve them, but file * pages can simply be left unmapped, then faulted back on demand. - * If that is ever changed (perhaps for mlock), update remap_page(). + * If that is ever changed (perhaps for mlock), update remap_folio(). */ if (folio_test_anon(folio)) try_to_migrate(folio, ttu_flags); @@ -3636,10 +3636,17 @@ bool unmap_huge_pmd_locked(struct vm_area_struct *v= ma, unsigned long addr, return __discard_anon_folio_pmd_locked(vma, addr, pmdp, folio); } =20 -static void remap_page(struct folio *folio, unsigned long nr, int flags) +static void remap_folio(struct folio *folio, unsigned long nr, int flags) { int i =3D 0; =20 + /* + * unmap_folio() installs migration entries only for anon folios, + * so currently only anon folios need to be remapped. File folios + * stay unmapped after the split and are faulted back on demand. + */ + VM_WARN_ON_FOLIO(!folio_test_anon(folio), folio); + for (;;) { remove_migration_ptes(folio, folio, TTU_RMAP_LOCKED | flags); i +=3D folio_nr_pages(folio); @@ -3723,7 +3730,7 @@ static void __split_folio_to_order(struct folio *foli= o, int old_order, * * Note that for mapped sub-pages of an anonymous THP, * PG_anon_exclusive has been cleared in unmap_folio() and is stored in - * the migration entry instead from where remap_page() will restore it. + * the migration entry instead from where remap_folio() will restore it. * We can still have PG_anon_exclusive set on effectively unmapped and * unreferenced sub-pages of an anonymous THP: we can simply drop * PG_anon_exclusive (-> PG_mappedtodisk) for these here. @@ -4064,7 +4071,7 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, if (need_remap) { if (!ret && !folio_is_device_private(folio)) ttu_flags =3D TTU_USE_SHARED_ZEROPAGE; - remap_page(folio, 1 << old_order, ttu_flags); + remap_folio(folio, 1 << old_order, ttu_flags); } =20 return ret; @@ -4186,7 +4193,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, fail: /* * If we want to use try_to_migrate() on file in unmap_folio, - * remember to add remap_page() and adapt it. + * remember to add remap_folio() and adapt it. */ xas_unlock_irq(xas); if (nr_shmem_dropped) --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D6B255221EC for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; cv=none; b=KyIjqo2cVQqvdOQy563xQ66oioXo5sgo2+vPICvbfSbCWXpgU7aWcDWAdh8ZW+nbW02qyuJZsvjTVzYr+OC5NOQOUY2JkxQk8YGt6biVZRn/laEcospbuw6NCzHu7Y6NxlwxwP4fovbkFwv7TKlyOJ0YlAKEmpmTfviLSny4yKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804736; c=relaxed/simple; bh=QzcJczxkbeS/pYSsNT+urBdCyxcTnTUrjYdSKS5ReGQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TuRNVAPE2gvtibSP+loM/KtaDTX7ShPGR40kOxCeyCczIF66Ecrlgody0v6/0JismA79GqQbl7OsyJUSAVgsiQer6hEr4KaCWjJTXvh0TZeL8R2Dnus9uYQ2mAmSJb7K63ag4/P1dOhTKKLKCo3xYzsXsgFHQRoa7EUIsbOLzGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GrH6PCaS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GrH6PCaS" Received: by smtp.kernel.org (Postfix) with ESMTPS id 97E80C2BCF4; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=QzcJczxkbeS/pYSsNT+urBdCyxcTnTUrjYdSKS5ReGQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=GrH6PCaSr7eVHHhyAc1BrCz4vC5zPKbA+SVWkejlnaxAQ4Pmefnt/eYadIGekki4Y jTOmh4YK9Hb44wQGrgWC/QTAG6ssEpyieMDqb8unw0yOIZ0DmPNIDFeLiQdK6CX2vf rMI9XOjrfQVC6WH6jo1oRFcduA301t0xyJFeV+enYj8wCQf2t4GtI7fj3RomDdR4l+ hJfYhcF8hT85J62sMStQVFcUyR5cD0nfpYy9PXbmQRGYLFOudVkEi4XRCGt4AsSm+V Nudy5b5AGwnlEz4tkjmUAv5haxtUQmW3E79wiN/hwD7ej2r4q97iMSXH3SDzWQOeeX d9RFdpDN62C3w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 82E7AC79FAA; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:14 +0800 Subject: [PATCH v4 10/17] mm/huge_memory: move the racy refcount check into unmap_folio() 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: <20260908-swap-thp-cleanup-v4-10-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=3389; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=NMmN0XNDJPzBYycE2fNg4sNy5B1+ud2QzkGI09EF/lM=; b=fDzQ+/qHyyE6OEBlwE+wQ4At5JOIzVAH+4OeBbdSkKrh7F9ey4Pcr6VwmnzyOnG30XZ/YNtz1 NBVuhaXTnJ/D43G85EoyuROTa9DltenBkGsdyrBvOcY5stu/a3ARKoC X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song The check only exists to avoid the expensive PMD-splitting unmap of a folio that cannot be split anyway. Move it from __folio_split() into unmap_folio(), right before the PMD split, so both the anon and file split helpers get the early check without repeating it. unmap_folio() now returns -EAGAIN if the check fails and the split helpers propagate the error. folio_split_unmapped() drops its own copy of the check: it works on already unmapped folios and the definitive folio_ref_freeze() in __folio_freeze_split_anon() still catches unexpected references. Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) Reviewed-by: Zi Yan --- mm/huge_memory.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index c5279c0d0e59..17bd2c053210 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3538,13 +3538,17 @@ void vma_adjust_trans_huge(struct vm_area_struct *v= ma, split_huge_pmd_if_needed(next, end); } =20 -static void unmap_folio(struct folio *folio) +static int unmap_folio(struct folio *folio) { enum ttu_flags ttu_flags =3D TTU_RMAP_LOCKED | TTU_SYNC | TTU_BATCH_FLUSH; =20 VM_BUG_ON_FOLIO(!folio_test_large(folio), folio); =20 + /* Racy check if we can split the page, before we split PMDs */ + if (folio_expected_ref_count(folio) !=3D folio_ref_count(folio) - 1) + return -EAGAIN; + if (folio_test_pmd_mappable(folio)) ttu_flags |=3D TTU_SPLIT_HUGE_PMD; =20 @@ -3559,6 +3563,8 @@ static void unmap_folio(struct folio *folio) try_to_unmap(folio, ttu_flags | TTU_IGNORE_MLOCK); =20 try_to_unmap_flush(); + + return 0; } =20 static bool __discard_anon_folio_pmd_locked(struct vm_area_struct *vma, @@ -4006,7 +4012,9 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, =20 if (folio_mapped(folio)) { need_remap =3D true; - unmap_folio(folio); + ret =3D unmap_folio(folio); + if (ret) + return ret; } =20 local_irq_disable(); @@ -4104,7 +4112,9 @@ static int __folio_freeze_split_file(struct folio *fo= lio, if (shmem_mapping(mapping)) end =3D shmem_fallocend(mapping->host, end); =20 - unmap_folio(folio); + ret =3D unmap_folio(folio); + if (ret) + return ret; =20 xas_lock_irq(xas); =20 @@ -4312,15 +4322,6 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, i_mmap_lock_read(mapping); } =20 - /* - * Racy check if we can split the page, before unmap_folio() will - * split PMDs - */ - if (folio_expected_ref_count(folio) !=3D folio_ref_count(folio) - 1) { - ret =3D -EAGAIN; - goto out_unlock; - } - if (is_anon) ret =3D __folio_freeze_split_anon(folio, new_order, split_at, true, list, split_type); @@ -4359,7 +4360,6 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, free_folio_and_swap_cache(new_folio); } =20 -out_unlock: if (anon_vma) { anon_vma_unlock_write(anon_vma); put_anon_vma(anon_vma); @@ -4407,9 +4407,6 @@ int folio_split_unmapped(struct folio *folio, unsigne= d int new_order) VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio); VM_WARN_ON_ONCE_FOLIO(!folio_test_anon(folio), folio); =20 - if (folio_expected_ref_count(folio) !=3D folio_ref_count(folio) - 1) - return -EAGAIN; - return __folio_freeze_split_anon(folio, new_order, &folio->page, false, NULL, SPLIT_TYPE_UNIFORM); } --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6C8AF523783 for ; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; cv=none; b=mv5LhOG9LYsk4U4+cDG4SzmKPny0sPTB9ZtDX4rj4VTeKvRn20+gA1sZNJwYpNmFLcdzbvETqdlryd8nfzStjbZPz5hQdgRHHZwnZZ+4RWLFn2SUWBnDcjIhJyrkqt/xE3Joqm3YmKWSIVevxA0DUL5yGC1oQWFjcH62dqyfnXI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; c=relaxed/simple; bh=I+u+i0OhFDYXj2sOqSO0jh8o9wLuzioiM46T0DNhMxY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lDuAIWBGgG8hSnZ0mu291iQcfQDwT8k4DEmjU3MrCRgy9n7mTB6xQSInPHEDt3SOWHxXXqtFDJRWROIIgVWfSFEHCahdF1kNerK8sroGnRGvcM9vALtnhuXiynPRAL7JgT9WimgB9k8I/TlQIAXTRHAbgDK3iY6Psi8CnmNsD50= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kLQ/9gyb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kLQ/9gyb" Received: by smtp.kernel.org (Postfix) with ESMTPS id B5B3CC2BCFF; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=I+u+i0OhFDYXj2sOqSO0jh8o9wLuzioiM46T0DNhMxY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=kLQ/9gybOIgpNAOdvEuIotJ4XzANmeSDRFv8eKBkyPd0ogwiXBS9Uw4jmdo8RuAZC GEa1E+xXHN9R4e3eFXi7o9oxGoMjoct9ExxILR6s2SnV8l5SdB9rUyhEY/XPDFFDub wOOaaGoXLVdZMXu69XIP7cXEWRUxTX3i+KT3GFYmdHrdkcjiu5rTQLdbcFQOscDdBo d1eVgN0C+YwFgwhusBYTyDmA4Mq2mjZbVJDrfYNDrCxWWJrJ9PiZa9BaBU1y7uub+V ypYy+YtLF96QNViswrOaqiyOoBpHqkjtJB1tak8phhbBbthpDb8PkAlVJcHsWFKdwi AHVPg1HrVXYiw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0640C79F9F; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:15 +0800 Subject: [PATCH v4 11/17] mm/huge_memory: move filemap management into the file split 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: <20260908-swap-thp-cleanup-v4-11-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=6255; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=vVlYGjPyxYAYmn821pQL1VWkwmnGIaxktKpsOp5j70I=; b=h4Qkg+uChtRz/caeznumouNlo2l0UEj+Q2LMUaWSS9ZV0h+sAcMuQo9rAMjROhgWQJgv8Dp/G RKH9/kdQNRXCl9ekDK+BxBA1TodPkFP8OKVALZoBywEdV1SKjNB9iXm X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song Only file split needs the filemap and xarray handling and related variables. Move them out of __folio_split() into the file helper so the helper is self-contained, and simplify the parameters. No functional change. Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) Reviewed-by: Zi Yan --- mm/huge_memory.c | 102 ++++++++++++++++++++++++---------------------------= ---- 1 file changed, 44 insertions(+), 58 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 17bd2c053210..c4910c0b6018 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4087,16 +4087,42 @@ static int __folio_freeze_split_anon(struct folio *= folio, =20 static int __folio_freeze_split_file(struct folio *folio, unsigned int new_order, struct page *split_at, - struct xa_state *xas, struct address_space *mapping, bool do_lru, struct list_head *list, enum split_type split_type) { + struct address_space *mapping =3D folio->mapping; + XA_STATE(xas, &mapping->i_pages, folio->index); struct folio *end_folio =3D folio_next(folio); struct folio *new_folio, *next; int nr_shmem_dropped =3D 0; + unsigned int min_order; struct lruvec *lruvec; pgoff_t end; - int ret; + gfp_t gfp; + int ret =3D 0; + + min_order =3D mapping_min_folio_order(mapping); + if (new_order < min_order) + return -EINVAL; + + gfp =3D current_gfp_context(mapping_gfp_mask(mapping) & GFP_RECLAIM_MASK); + if (!filemap_release_folio(folio, gfp)) + return -EBUSY; + + mapping_set_update(&xas, mapping); + + if (split_type =3D=3D SPLIT_TYPE_UNIFORM) { + int old_order =3D folio_order(folio); + + xas_set_order(&xas, folio->index, new_order); + xas_split_alloc(&xas, folio, old_order, gfp); + if (xas_error(&xas)) { + ret =3D xas_error(&xas); + goto fail_free; + } + } + + i_mmap_lock_read(mapping); =20 /* Currently device private folios can only back anonymous memory. */ VM_WARN_ON_ONCE_FOLIO(folio_is_device_private(folio), folio); @@ -4114,15 +4140,15 @@ static int __folio_freeze_split_file(struct folio *= folio, =20 ret =3D unmap_folio(folio); if (ret) - return ret; + goto fail_mmap_unlock; =20 - xas_lock_irq(xas); + xas_lock_irq(&xas); =20 /* * Check if the folio is present in page cache. * We assume all tail are present too, if folio is there. */ - if (xas_load(xas) !=3D folio) { + if (xas_load(&xas) !=3D folio) { ret =3D -EAGAIN; goto fail; } @@ -4149,7 +4175,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, if (do_lru) lruvec =3D folio_lruvec_lock(folio); =20 - ret =3D __split_frozen_folio(folio, new_order, split_at, xas, + ret =3D __split_frozen_folio(folio, new_order, split_at, &xas, mapping, split_type); =20 /* @@ -4205,9 +4231,19 @@ static int __folio_freeze_split_file(struct folio *f= olio, * If we want to use try_to_migrate() on file in unmap_folio, * remember to add remap_folio() and adapt it. */ - xas_unlock_irq(xas); + xas_unlock_irq(&xas); +fail_mmap_unlock: if (nr_shmem_dropped) shmem_uncharge(mapping->host, nr_shmem_dropped); + /* + * Drop the mapping while the inode is still pinned. @folio stays + * locked and present in the page cache, so eviction cannot free + * the inode yet, nothing past this point may touch the inode or + * the mapping. + */ + i_mmap_unlock_read(mapping); +fail_free: + xas_destroy(&xas); return ret; } =20 @@ -4236,11 +4272,9 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, struct page *split_at, struct page *lock_at, struct list_head *list, enum split_type split_type) { - XA_STATE(xas, &folio->mapping->i_pages, folio->index); struct folio *end_folio =3D folio_next(folio); bool is_anon =3D folio_test_anon(folio); struct mem_cgroup *memcg, *old_memcg; - struct address_space *mapping =3D NULL; struct anon_vma *anon_vma =3D NULL; int old_order =3D folio_order(folio); struct folio *new_folio, *next; @@ -4287,60 +4321,15 @@ static int __folio_split(struct folio *folio, unsig= ned int new_order, goto out; } anon_vma_lock_write(anon_vma); - mapping =3D NULL; - } else { - unsigned int min_order; - gfp_t gfp; - - mapping =3D folio->mapping; - min_order =3D mapping_min_folio_order(mapping); - if (new_order < min_order) { - ret =3D -EINVAL; - goto out; - } - - gfp =3D current_gfp_context(mapping_gfp_mask(mapping) & - GFP_RECLAIM_MASK); - - if (!filemap_release_folio(folio, gfp)) { - ret =3D -EBUSY; - goto out; - } - - mapping_set_update(&xas, mapping); - - if (split_type =3D=3D SPLIT_TYPE_UNIFORM) { - xas_set_order(&xas, folio->index, new_order); - xas_split_alloc(&xas, folio, old_order, gfp); - if (xas_error(&xas)) { - ret =3D xas_error(&xas); - goto out; - } - } - - anon_vma =3D NULL; - i_mmap_lock_read(mapping); } =20 if (is_anon) ret =3D __folio_freeze_split_anon(folio, new_order, split_at, true, list, split_type); else - ret =3D __folio_freeze_split_file(folio, new_order, split_at, &xas, mapp= ing, + ret =3D __folio_freeze_split_file(folio, new_order, split_at, true, list, split_type); =20 - /* - * Drop the mapping while the inode is still pinned. @folio stays - * locked and present in the page cache until the loop below, so - * eviction cannot free the inode yet; @lock_at is not enough, it may - * be a tail beyond EOF that the split already dropped from the page - * cache. Nothing past this point may touch the inode or the mapping. - */ - if (mapping) { - i_mmap_unlock_read(mapping); - mapping =3D NULL; - } - /* * Unlock all after-split folios except the one containing * @lock_at page. If @folio is not split, it will be kept locked. @@ -4364,14 +4353,11 @@ static int __folio_split(struct folio *folio, unsig= ned int new_order, anon_vma_unlock_write(anon_vma); put_anon_vma(anon_vma); } - if (mapping) - i_mmap_unlock_read(mapping); out: /* restore to caller's old_memcg */ set_active_memcg(old_memcg); mem_cgroup_put(memcg); out_no_memcg: - xas_destroy(&xas); if (is_pmd_order(old_order)) count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED); count_mthp_stat(old_order, !ret ? MTHP_STAT_SPLIT : MTHP_STAT_SPLIT_FAILE= D); --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 EE5EF5221ED for ; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; cv=none; b=ocjsRmLEilUAX9JtpMmXG6t7PgKxrVDaSpuQbClJiJ02zwi7nkErTNFcS8U/pM9P168hHECyb7yYV7XxJM5YAY+taIEir6Q5sxzhgq98Xe7ZGKmOzh3QuE9D7Un/SmbxXAyBAnUseUeIYgtThOlQaHWjfDbX0h4CVjSB3DBUeKg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; c=relaxed/simple; bh=tVWK3YtWyyptpKhnWj6y5t/GlQNNfc+ftcR4tLibrxw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZjhX98yQNuU2J2acGBVa1VqUeSiji+B+Ci8H4hC0C0RRFv/QjD8xERK9dHVW6rFI3/uPLIA7qsFkwwkr3Wc7iqoVzoQ1vUeRwlxbvOPF4oKuWJ6RIarDKuyC0vdjC2nJaTg5F8NVSVysPtkE99Mzy4Lgx0RCAY/WWHVptej/Ezo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kr6wGEVE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kr6wGEVE" Received: by smtp.kernel.org (Postfix) with ESMTPS id D0B30C2BD04; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=tVWK3YtWyyptpKhnWj6y5t/GlQNNfc+ftcR4tLibrxw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=kr6wGEVECmEJrJvPwdah5IS686Rbp0sJcBiUfhIGIYfarDpM5kLB8tM2ulZP13LNS gap/EuUun3lfOtDpaYESOzVeby6z1Cg324WRQW9PKny7DrcAUybRjH0DCnspSo+2jd veIijqfPwtv5QpZflg0IEDfkV4UPS/v49MFQAgbCIPKWw6pnIjY2II942dpqtFnH3+ tuFXT1fmIdMjWrWNEhE2Cbu8tEzkmn59/mm603RKwEpurY90sXo0JbJgtiVMv/QaNO INdArTw6WROhPk5Gh09lt/DB4B6wJJjegtFFCafqDsPtgHIquNgH80nN39t6hgjrbr hK1TKWgT8ByBg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA92FC79FA0; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:16 +0800 Subject: [PATCH v4 12/17] mm/huge_memory: move anon_vma handling into the anon split 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: <20260908-swap-thp-cleanup-v4-12-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=5440; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=X2P4cDrUHVxhy5NF0vdUxXcb6y1qZnECR0W8Rgpwvlc=; b=v8Z0yYqIgMrwAWzCPdCTt0cJposY5TVpHL4ti7vOOeL4283+2IhgBZV5PBP5qd6T/i0Ka0kMu OjJxe2nKqfyDOQk5+875jZzJVMipNoOkI8v1PlihNqtS3r3ng5Koyc9 X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song Only anon split needs the anon_vma, and it only needs it to unmap and remap. Move the folio_get_anon_vma()/anon_vma_lock_write() pair out of __folio_split() into the anon helper next to the folio_mapped() check that already gates unmap_folio(). This makes the anon_vma conditional on folio_mapped(), which is a behaviour change but should be fine. folio_get_anon_vma() returns NULL whenever !folio_mapped(), so an anon folio with folio_mapcount() =3D=3D 0 used to get -EBUSY from split_huge_page() and is now split instead. The realistic case is a THP that has been fully swapped out and is still in the swap cache: swap PTEs do not contribute mapcount, so it is !folio_mapped() but still alive. That should be safe and right to have because: - folio_ref_freeze() below still rejects a folio that picked up any reference, a mapping or a GUP pin, in the meantime. - A parallel split is excluded by the folio lock. The anon_vma write lock was added to serialize split in commit 062f1af2170a ("mm: thp: acquire the anon_vma rwsem for write during split"), when split_huge_page() did not hold the folio lock throughout. commit e9b61f19858a ("thp: reintroduce split_huge_page()") later made the folio lock a caller requirement and added the folio_ref_freeze() scheme, so that has been covered ever since. - Unmapped path is already exercised by folio_split_unmapped(), and the swap cache split already runs well for a partially swapped-out mapped THP. - folio_get_anon_vma() and folio_lock_anon_vma_read() both bail out on !folio_mapped() before taking the anon_vma lock, so there is nothing to lock against. For mapped folios the anon_vma write lock is now released before __folio_split() unlocks the after-split sub-folios, where previously it was held across that loop, that window is harmless as the sub-folios stay folio-locked and ref pinned. Signed-off-by: Kairui Song Reviewed-by: Zi Yan --- mm/huge_memory.c | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index c4910c0b6018..53614b875794 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4005,16 +4005,31 @@ static int __folio_freeze_split_anon(struct folio *= folio, struct swap_cluster_info *ci =3D NULL; struct folio *new_folio, *next; int old_order =3D folio_order(folio); + struct anon_vma *anon_vma =3D NULL; enum ttu_flags ttu_flags =3D 0; struct lruvec *lruvec; - bool need_remap =3D false; int ret =3D 0; =20 + /* + * Unmap/remap needs the anon_vma. The caller does not necessarily + * hold an mmap_lock that would prevent the anon_vma from + * disappearing, so we first take a reference and lock it. + * + * An unmapped folio needs none of this: folio_get_anon_vma() and + * folio_lock_anon_vma_read() both bail out on !folio_mapped() + * before taking the lock, and folio_ref_freeze() below still + * rejects a folio that picked up a reference meanwhile. Note + * a swapped-out THP counts as unmapped here as swap PTEs do + * not contribute mapcount, and they are splittable. + */ if (folio_mapped(folio)) { - need_remap =3D true; + anon_vma =3D folio_get_anon_vma(folio); + if (!anon_vma) + return -EBUSY; + anon_vma_lock_write(anon_vma); ret =3D unmap_folio(folio); if (ret) - return ret; + goto out_unlock; } =20 local_irq_disable(); @@ -4076,11 +4091,16 @@ static int __folio_freeze_split_anon(struct folio *= folio, swap_cluster_unlock(ci); out_no_split: local_irq_enable(); - if (need_remap) { + if (anon_vma) { if (!ret && !folio_is_device_private(folio)) ttu_flags =3D TTU_USE_SHARED_ZEROPAGE; remap_folio(folio, 1 << old_order, ttu_flags); } +out_unlock: + if (anon_vma) { + anon_vma_unlock_write(anon_vma); + put_anon_vma(anon_vma); + } =20 return ret; } @@ -4275,7 +4295,6 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, struct folio *end_folio =3D folio_next(folio); bool is_anon =3D folio_test_anon(folio); struct mem_cgroup *memcg, *old_memcg; - struct anon_vma *anon_vma =3D NULL; int old_order =3D folio_order(folio); struct folio *new_folio, *next; int ret; @@ -4306,23 +4325,6 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, memcg =3D get_mem_cgroup_from_folio(folio); old_memcg =3D set_active_memcg(memcg); =20 - if (is_anon) { - /* - * The caller does not necessarily hold an mmap_lock that would - * prevent the anon_vma disappearing so we first we take a - * reference to it and then lock the anon_vma for write. This - * is similar to folio_lock_anon_vma_read except the write lock - * is taken to serialise against parallel split or collapse - * operations. - */ - anon_vma =3D folio_get_anon_vma(folio); - if (!anon_vma) { - ret =3D -EBUSY; - goto out; - } - anon_vma_lock_write(anon_vma); - } - if (is_anon) ret =3D __folio_freeze_split_anon(folio, new_order, split_at, true, list, split_type); @@ -4349,11 +4351,6 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, free_folio_and_swap_cache(new_folio); } =20 - if (anon_vma) { - anon_vma_unlock_write(anon_vma); - put_anon_vma(anon_vma); - } -out: /* restore to caller's old_memcg */ set_active_memcg(old_memcg); mem_cgroup_put(memcg); --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 0F0F85221EE for ; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; cv=none; b=bF0vjxI1Ky6Wya2qw7HLhKjLvEkpTdj/5xYfJmNEPXDtzlVhQtmfDxcik7cwgChnmFcKdLZt+kFwJOvaW5e6iM/paFMC5CKY6uKYzbcVjJY7YUrlL4lAzs2c00picUzYK3DiOgR79Xxy/5us9nxxbJya/CqcY8CFUxQgsZ2SK94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; c=relaxed/simple; bh=LirXvJJX0Y/6Fo5sXUix83AOPmuYDoroUD8pSAtNyj0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iVIaZt2v32sJiRLHZ0hrHWRo8/LzKL4NlbigeWXOk/aQqeFSpGNArLve4LWWR4HeFU6BMlmW+hsvDgvnPW+1Xjq6mzk2F2IkTImcg7pCQP3liKgXlPrQrP+BpU7JlTvJVQvsK9Q4mbty0jbp+PcVJ7ZxItVo66+2yI6N+k/Frh4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QgOTHUlX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QgOTHUlX" Received: by smtp.kernel.org (Postfix) with ESMTPS id E5796C2BD01; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804736; bh=LirXvJJX0Y/6Fo5sXUix83AOPmuYDoroUD8pSAtNyj0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=QgOTHUlX0OwjqVlEVvoWBbOdTBNWxKz0jkjh5UA6t3TmSY4Z8Ai2LAFlhkpYxg+DV HbHktoBEk9AyN01vgsxxxxSxrwlwBCeH+iD864Rp+D302iNQlbLrbO9wat3JzlCQI3 aMNMvf9fn2UbBj9dk3aLxexJU0Oj77+X25p/hmTLaH2OH2sejNV41V9eCWKQLiRe8w MOmaNj0VKRYmIecePX0jdCWXD/CrTOSsSH4PjLaO3lE7P2DqiCb4EjCfWEL/KkG8nT HjqK/ywP5OnoKptuX7lBN8QUdOgY71avmfHaZyz1lWUxsdAA1L/VIU0i1a9QL/nof0 OFWVxhGw0Sq6w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1795C79F99; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:17 +0800 Subject: [PATCH v4 13/17] mm/huge_memory: move memcg switch into the file split 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: <20260908-swap-thp-cleanup-v4-13-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=3655; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=uIbn+TS0iIeP9vFYqPvx1IGgAoImfhKW84wopAEDXo4=; b=VZnf3gSCQZgZbn1iZTc2hUb/vK13UG9e9hi8wvd77ElBa98VWNojeQ7JlQMREeFcR8EnJ7om9 /E6JMsBGRdlAc1zXWgKxvjQWVvdanDEgVWQVm4KHeLzleFEL4pTBT97 X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song The xarray node allocations in __folio_freeze_split_file() need to be charged to the folio's memcg, so move the memcg switch from __folio_split() into the helper. The anon split helper and the after-split folio freeing perform no chargeable allocations, so no memcg handling is left in __folio_split(). Rename its out_no_memcg label to out. Acked-by: Zi Yan Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) --- mm/huge_memory.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 53614b875794..ccd48cd5f94b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4113,6 +4113,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, struct address_space *mapping =3D folio->mapping; XA_STATE(xas, &mapping->i_pages, folio->index); struct folio *end_folio =3D folio_next(folio); + struct mem_cgroup *memcg, *old_memcg; struct folio *new_folio, *next; int nr_shmem_dropped =3D 0; unsigned int min_order; @@ -4125,9 +4126,18 @@ static int __folio_freeze_split_file(struct folio *f= olio, if (new_order < min_order) return -EINVAL; =20 + /* + * Switch to folio's memcg as xarray node allocation can happen and + * needs to charge to it. + */ + memcg =3D get_mem_cgroup_from_folio(folio); + old_memcg =3D set_active_memcg(memcg); + gfp =3D current_gfp_context(mapping_gfp_mask(mapping) & GFP_RECLAIM_MASK); - if (!filemap_release_folio(folio, gfp)) - return -EBUSY; + if (!filemap_release_folio(folio, gfp)) { + ret =3D -EBUSY; + goto fail_free; + } =20 mapping_set_update(&xas, mapping); =20 @@ -4263,6 +4273,9 @@ static int __folio_freeze_split_file(struct folio *fo= lio, */ i_mmap_unlock_read(mapping); fail_free: + /* Restore the previously active memcg */ + set_active_memcg(old_memcg); + mem_cgroup_put(memcg); xas_destroy(&xas); return ret; } @@ -4294,7 +4307,6 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, { struct folio *end_folio =3D folio_next(folio); bool is_anon =3D folio_test_anon(folio); - struct mem_cgroup *memcg, *old_memcg; int old_order =3D folio_order(folio); struct folio *new_folio, *next; int ret; @@ -4304,27 +4316,20 @@ static int __folio_split(struct folio *folio, unsig= ned int new_order, =20 if (folio !=3D page_folio(split_at) || folio !=3D page_folio(lock_at)) { ret =3D -EINVAL; - goto out_no_memcg; + goto out; } =20 if (new_order >=3D old_order) { ret =3D -EINVAL; - goto out_no_memcg; + goto out; } =20 ret =3D folio_check_splittable(folio, new_order, split_type); if (ret) { VM_WARN_ONCE(ret =3D=3D -EINVAL, "Tried to split an unsplittable folio"); - goto out_no_memcg; + goto out; } =20 - /* - * switch to folio's memcg as xarray node allocation can happen and - * needs to charge to it. - */ - memcg =3D get_mem_cgroup_from_folio(folio); - old_memcg =3D set_active_memcg(memcg); - if (is_anon) ret =3D __folio_freeze_split_anon(folio, new_order, split_at, true, list, split_type); @@ -4351,10 +4356,7 @@ static int __folio_split(struct folio *folio, unsign= ed int new_order, free_folio_and_swap_cache(new_folio); } =20 - /* restore to caller's old_memcg */ - set_active_memcg(old_memcg); - mem_cgroup_put(memcg); -out_no_memcg: +out: if (is_pmd_order(old_order)) count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED); count_mthp_stat(old_order, !ret ? MTHP_STAT_SPLIT : MTHP_STAT_SPLIT_FAILE= D); --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 273A35221F9 for ; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; cv=none; b=fXzWBm3huQV53FkuOrotMypsnVNF4/hqzZO8SXqQbZ7NoBl8OguKe1SxPNF6l3ZSUGznuj2WdTtJ9FJTb4rNvnvQm1DyMg9Q2G5rS/ttlx7ndI2Mfp/RXvQXFUUejDAMMGUvj5OThnbq7tTHErfiWWnZH4oFTIZ8Z9xv+uctX8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; c=relaxed/simple; bh=kkuX54NYW1o9dDD+/jciNXKhI+65D0lfRKDdNOxp11Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BV1DErflRyvJ4TSldR4z0ofZncJIsYsw5gJG1BQxFLUmeN7ax0NEvPq/oNh1LNXCaAAKBmCflaJApJBQ7d8HEx7Gf6DSS5hvQ4JQvKK59FTWzoUcyRjXETZYKDE/xKmYOpqtnvPAB/TbgiGXZA65idVXCJpUc/FUtERMO5yE8/I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QQrq237+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QQrq237+" Received: by smtp.kernel.org (Postfix) with ESMTPS id 06DE7C2BCC7; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804737; bh=kkuX54NYW1o9dDD+/jciNXKhI+65D0lfRKDdNOxp11Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=QQrq237+I0tlz8KHBi0SILSyzD8pXJt9oxYxgvUXg6SFCh1diq/Mg7xpLdxLWHNXg SAdelRX6DdWWWz9KYf3NsdFdM+HFlvVMJpI+f0Ioy2GA7wQvOclumtcbFyg/OeiTzG AJ8GApA1obtyf5b8RyazxsrxURoCqoqUd+h1tOYU6gjIQ8aR1qyx3p7eWjvs02vuHE pb5mhP87qyiiVzA1Cnze9FpJJ2Pr4Sv3q45Yp/Rv2O6VnaKnNgo0LTVsR7b7Z7ZpUX HFqNDCmw5XoMJd2XGaQ1+OV2gxepUFs/rBUK0HVjJc+5zWYRXWS5wpQaHRDGbKM67I s8IaWcVy42TeQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6703C79FAB; Mon, 7 Sep 2026 18:12:16 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:18 +0800 Subject: [PATCH v4 14/17] mm/huge_memory: drop the unused do_lru argument of the file split 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: <20260908-swap-thp-cleanup-v4-14-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=2439; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=a/jf5N0ceVT9ic/8DVL2LfIrSgCiaeltQ7+TGC4eqog=; b=UUxTwZ1zaeh+CLxeq2MurhCTVbY3kFNfbJnrl2RetkKuvrSFYHsrIxGIEj+I4hCcBR+FgAiGf 0Gh6OORkTjmDxX0ae4Ym/nKlUhGjPAytxiXOqn5vI+jhtP/yJcvAduz X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song The only caller of __folio_freeze_split_file() always passes do_lru as true, so the argument and the branches gated on it are dead code. Drop it. Reviewed-by: Zi Yan Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) --- mm/huge_memory.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index ccd48cd5f94b..6ce58a5d93d8 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4107,8 +4107,7 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, =20 static int __folio_freeze_split_file(struct folio *folio, unsigned int new_order, struct page *split_at, - bool do_lru, struct list_head *list, - enum split_type split_type) + struct list_head *list, enum split_type split_type) { struct address_space *mapping =3D folio->mapping; XA_STATE(xas, &mapping->i_pages, folio->index); @@ -4202,9 +4201,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, } =20 /* lock lru list/PageCompound, ref frozen by page_ref_freeze */ - if (do_lru) - lruvec =3D folio_lruvec_lock(folio); - + lruvec =3D folio_lruvec_lock(folio); ret =3D __split_frozen_folio(folio, new_order, split_at, &xas, mapping, split_type); =20 @@ -4226,8 +4223,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, folio_ref_unfreeze(new_folio, folio_cache_ref_count(new_folio) + 1); =20 - if (do_lru) - lru_add_split_folio(folio, new_folio, lruvec, list); + lru_add_split_folio(folio, new_folio, lruvec, list); =20 /* Add the new folio to the page cache. */ if (new_folio->index < end) { @@ -4253,9 +4249,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, * and its caller can see stale page cache entries. */ folio_ref_unfreeze(folio, folio_cache_ref_count(folio) + 1); - - if (do_lru) - lruvec_unlock(lruvec); + lruvec_unlock(lruvec); fail: /* * If we want to use try_to_migrate() on file in unmap_folio, @@ -4335,7 +4329,7 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, true, list, split_type); else ret =3D __folio_freeze_split_file(folio, new_order, split_at, - true, list, split_type); + list, split_type); =20 /* * Unlock all after-split folios except the one containing --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 401515221FA for ; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; cv=none; b=cWJhAWA7VFWNImof8v9f8cpWaCfLqirpz/zRnxYIY4J71mdhqT2YWHsEZ7ugQP4ySM4zojafi9MsVhx3KvoGpunB6gVy236G+OWvHy4lJZ/+3FgGBQYSGWKcJFfkEZp/Twvbu6y1hRGesCi/V8IIV3Y2fFg1nbcCAssEJeLMSyQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; c=relaxed/simple; bh=R9EpXQ7qONV9lpiPA+ohrrtEztCFHdKrqYYyIfuXzkM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MVV+w9JqRymFFVlhUnDe3XqUKkGjH+iJ3UIwnxZmP1lpxnD9MU5C2nQudjNe9RxP4HieHgzFCSU3/F4nTTikbqSHKLj38wAqq7QnnJNW5oyv0M1w9OgtD5CxC/tNOZOME5c5n0mXj3YBoLWTgPvXt0+Ut1Z/FAGVP06Sbg4WzA8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MHiPUYIR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MHiPUYIR" Received: by smtp.kernel.org (Postfix) with ESMTPS id 219A3C2BD00; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804737; bh=R9EpXQ7qONV9lpiPA+ohrrtEztCFHdKrqYYyIfuXzkM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=MHiPUYIRtdY7HIlAIkR5pthbc0iYl3GgcEwafx81eSdxVd5LmTaaKzh/o3a6k2Q8K ND94eX6aI/avv+Ymw+yTd1jutgAu4wmohmp+VhPncy5NlwE8xCfEJPGjtvz/aDRghd UTinD472/q6i5eAAN57e9RurkQh4gURsaORfCMh6W7ASzGKHVQgpt9E2ixm9LbsAdg MH5vQ9JbihRLSGDUXu+dd6GHvTQMPG7YRntPL6Rectr2+0gw4A++NqK3nmnn1JUIJZ JmjLaBlPxo5x873mRYaYvVPtPdqFOrUja7P1vCbBi6Wq7b/orWarztU95c1P1gvc+X RJEdNkf6PyBvg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C922C79F99; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:19 +0800 Subject: [PATCH v4 15/17] mm/huge_memory: clean up after-split folio freeing in __folio_split 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: <20260908-swap-thp-cleanup-v4-15-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=2589; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=LPw0g31E5D9zX1H4eUm1VXyklDl8xmiD0cmIubk3YCw=; b=H3zOLrM7H20Uz/hjtabEwQXX2WvQZwP9+1s7jTWTHc7SOHnZFzVYPLkFCTTIVNhSmZkWHxt0P XxpW4+ZB8q8DZJJF09UiRQTz/rxIMXQuGMgPrgv7XnqMkclK9SKlIsx X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song Replace free_folio_and_swap_cache() with an explicit folio_free_swap() and folio_put() in the after-split loop. free_folio_and_swap_cache() unlocks the folio, then free_swap_cache() must trylock it again and re-check folio_mapped() before freeing the swap cache entries; if the trylock loses a race, the entries are left behind even though the folio reference is dropped. The sub folios are still locked and unmapped here, so just directly call folio_free_swap() under the lock, unlock and drop the reference. This makes the swap cache freeing deterministic and the reference drop explicit. Reviewed-by: Zi Yan Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) --- mm/huge_memory.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 6ce58a5d93d8..f2862556d715 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4300,7 +4300,8 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, struct list_head *list, enum split_type split_type) { struct folio *end_folio =3D folio_next(folio); - bool is_anon =3D folio_test_anon(folio); + const bool is_anon =3D folio_test_anon(folio); + const bool is_swapcache =3D folio_test_swapcache(folio); int old_order =3D folio_order(folio); struct folio *new_folio, *next; int ret; @@ -4340,14 +4341,16 @@ static int __folio_split(struct folio *folio, unsig= ned int new_order, if (new_folio =3D=3D page_folio(lock_at)) continue; =20 - folio_unlock(new_folio); /* * Subpages whose mapping has been zapped may be freed * earlier, but freeing them requires taking the - * lru_lock, so we defer put_page() on tail pages until + * lru_lock, so we defer folio_put() on tail pages until * after the split completes. */ - free_folio_and_swap_cache(new_folio); + if (is_swapcache && !folio_mapped(new_folio)) + folio_free_swap(new_folio); + folio_unlock(new_folio); + folio_put(new_folio); } =20 out: @@ -4374,7 +4377,7 @@ static int __folio_split(struct folio *folio, unsigne= d int new_order, * isolated from LRU (if applicable) * * Upon return, the folio is not remapped, split folios are not added to L= RU, - * free_folio_and_swap_cache() is not called, and new folios remain locked. + * folio_free_swap() is not called, and new folios remain locked. * * Return: 0 on success, -EAGAIN if the folio cannot be split (e.g., due to * insufficient reference count or extra pins). --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 5C87B523781 for ; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; cv=none; b=YYziLzBt2V2Z2iqI1SXz6SN/a5184gq4lEacziPrSBqnSjp81O7TJx/ifNshwvRsgJdUvC3bSXlQc1njjo0qlxQ5uAAR70mkyGEnhj5+aXrypWL1SWSh36LGFNSbl/zD9tF+wy3aqNh60CrhyslI1U34QZkMKDHBED1xC5R9fVU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; c=relaxed/simple; bh=CKnadc+7pWXJlgz4J8xzzvddy/Ve8PJlE6DTq8avhuU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CJ/oJ/5Luc1OLy8f+FBrqdhCwSBHnJv50XhmF0dB3aCmegMUP48mLgGZfdJyEL6GX5bTJAzQDCUJufkhQk9QQZJxdOlGF7lOkQey9ZHNkQOMGIGcLFRLCqihF5fZ2BDEe5nqOvPsQGhyMWwCFPwQ09c/xHNWjQSzxuwgr0CQgtc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Pg9LUZlo; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Pg9LUZlo" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3D7ACC2BD01; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804737; bh=CKnadc+7pWXJlgz4J8xzzvddy/Ve8PJlE6DTq8avhuU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Pg9LUZlohuQ3KwhtKtfYnhOTWDqL0C9cHdWVObXskUDJonNpsGphwSFI9DV96SVma mi/zgru98Z674Ak08rySE6ghTLnOvbDdtrfoFObjwe7bX9U0aNEwrVLtwpy9W8InxS eEtjnSCOoct3xMdJr/mjTILWXeOKsydV5ej5tDySUu04mA64JlUbxfBiDNad2QbqfA S8wqFiB8ounwkKbN/qIDR7ZwporiTWUnlAVq0Ph06J2IcpDryY4k+cXTWXF0Js3nJH lgBh/HFpRO7dLHqbl8y+B/gfqlqcmv0xj1Qj1sWfJq/tNO/O7/cP8bs10ZnZV9x1r0 foesTlInjm26w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27046C79FAA; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:20 +0800 Subject: [PATCH v4 16/17] mm/huge_memory: count only swap cache refs in anon folio split 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: <20260908-swap-thp-cleanup-v4-16-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=4303; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=x2XvuBUmjQ9RNkNardz/nbyUAIqiAzW7DbxwXCBxFbw=; b=0Gsh+74RbR9mPQw8kiFGdkSNC+du48fBuP6BSEuvvogqBLljdob48chw7eBIYhZ2o7By15fSR +JdLUcoRtWQBC2dRnrWTaaESvHKWcD1NTESkgxQ6SsuNAZdHCnkXlus X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song Only __folio_freeze_split_anon() sees anon folios and swap cache folios now. The file split helper only handles page cache folios, which hold exactly folio_nr_pages() references. Rename folio_cache_ref_count() to folio_swapcache_ref_count() and drop the anon check so the helper counts what its name says. The file split helper now uses folio_nr_pages() directly. No feature change. Reviewed-by: Zi Yan Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) --- mm/huge_memory.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index f2862556d715..661b1c747c33 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3989,10 +3989,10 @@ int folio_check_splittable(struct folio *folio, uns= igned int new_order, return 0; } =20 -/* Number of folio references from the pagecache or the swapcache. */ -static unsigned int folio_cache_ref_count(const struct folio *folio) +/* Number of folio references from the swapcache. */ +static unsigned int folio_swapcache_ref_count(const struct folio *folio) { - if (folio_test_anon(folio) && !folio_test_swapcache(folio)) + if (!folio_test_swapcache(folio)) return 0; return folio_nr_pages(folio); } @@ -4034,7 +4034,7 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, =20 local_irq_disable(); =20 - if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) { + if (!folio_ref_freeze(folio, folio_swapcache_ref_count(folio) + 1)) { ret =3D -EAGAIN; goto out_no_split; } @@ -4075,7 +4075,7 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, next =3D folio_next(new_folio); zone_device_private_split_cb(folio, new_folio); folio_ref_unfreeze(new_folio, - folio_cache_ref_count(new_folio) + 1); + folio_swapcache_ref_count(new_folio) + 1); if (do_lru) lru_add_split_folio(folio, new_folio, lruvec, list); if (ci) @@ -4083,7 +4083,7 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, } =20 zone_device_private_split_cb(folio, NULL); - folio_ref_unfreeze(folio, folio_cache_ref_count(folio) + 1); + folio_ref_unfreeze(folio, folio_swapcache_ref_count(folio) + 1); =20 if (do_lru) lruvec_unlock(lruvec); @@ -4112,6 +4112,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, struct address_space *mapping =3D folio->mapping; XA_STATE(xas, &mapping->i_pages, folio->index); struct folio *end_folio =3D folio_next(folio); + long old_nr_pages =3D folio_nr_pages(folio); struct mem_cgroup *memcg, *old_memcg; struct folio *new_folio, *next; int nr_shmem_dropped =3D 0; @@ -4182,22 +4183,16 @@ static int __folio_freeze_split_file(struct folio *= folio, goto fail; } =20 - if (!folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) { + if (!folio_ref_freeze(folio, old_nr_pages + 1)) { ret =3D -EAGAIN; goto fail; } =20 - if (folio_test_pmd_mappable(folio) && - new_order < HPAGE_PMD_ORDER) { - int nr =3D folio_nr_pages(folio); - - if (folio_test_swapbacked(folio)) { - lruvec_stat_mod_folio(folio, - NR_SHMEM_THPS, -nr); - } else { - lruvec_stat_mod_folio(folio, - NR_FILE_THPS, -nr); - } + if (folio_test_pmd_mappable(folio) && new_order < HPAGE_PMD_ORDER) { + if (folio_test_swapbacked(folio)) + lruvec_stat_mod_folio(folio, NR_SHMEM_THPS, -old_nr_pages); + else + lruvec_stat_mod_folio(folio, NR_FILE_THPS, -old_nr_pages); } =20 /* lock lru list/PageCompound, ref frozen by page_ref_freeze */ @@ -4221,7 +4216,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, next =3D folio_next(new_folio); =20 folio_ref_unfreeze(new_folio, - folio_cache_ref_count(new_folio) + 1); + folio_nr_pages(new_folio) + 1); =20 lru_add_split_folio(folio, new_folio, lruvec, list); =20 @@ -4248,7 +4243,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, * Otherwise, a parallel folio_try_get() can grab @folio * and its caller can see stale page cache entries. */ - folio_ref_unfreeze(folio, folio_cache_ref_count(folio) + 1); + folio_ref_unfreeze(folio, folio_nr_pages(folio) + 1); lruvec_unlock(lruvec); fail: /* --=20 2.55.0 From nobody Fri Sep 25 23:10:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 78C15521222 for ; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; cv=none; b=RI1imcEqUsSh5DXUaV2gHqof/0q9wWacG3Zu7Vn+MbaihRc4N9NhmWUJcBpfTT8LFi1DeSVQHP4UpTXZTpWndmoNG3p1fpOuQO0BfwKPL7JYKJ+scN+hscrnhMfmbtlNYcOSAY1fR4gWJYn3SMQrwqS/MLOoTW7Fzbp3cD86OZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788804737; c=relaxed/simple; bh=0nJtL0HsBIYjbUStq8DzcAyHgpyDmq6mW315bcuSuCQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PGf8OaFvJcGuZH9Thj2OdjTniFyycJ2BJNtL6sDom4pGoMHfS6+BW7PPnUITG+dCuhEicKs413s09Uqec5/NQ4qTJzcn6k+yEPfd5o3W+uekntAki0TbW6R/Fb+ZqveFqJaeWFX4GEwIdreKyjYhCR2lMZWgZPE5bbhb2Hzl79Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B8ii1J5/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="B8ii1J5/" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5BFACC32781; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1788804737; bh=0nJtL0HsBIYjbUStq8DzcAyHgpyDmq6mW315bcuSuCQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=B8ii1J5/fJ+qtUENkB7cyl/EiK9fgmt22pky/q4HHuldn+iOimziFLHfOPDcKlwIl Cr+6x5EA73NIUdHWnYBnhszVurFiFj+PyiIMVF9gE2Dwjs/FTyJuz7sIgv9Sfs4bk1 CO0p/QeIphf06vEVn64Dm1sqEOZMiQX80zDH4MVWBfyZs0C1L6ee63YaRuWT757alx Ofh8/ksBbRd0Sv9sv5tHcgUWM7c628N78n8yBa2/FQ0yvQLoP0qAJ8sAG+WeZjprkM T1rqcHT1StrPl6+GacTOMzpR4iX+SH+epn2h+AAWKd66CuDSu/9kWJeCENgr/iD2iZ NSXL5g/Uw6yDw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42527C79FA0; Mon, 7 Sep 2026 18:12:17 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 08 Sep 2026 02:12:21 +0800 Subject: [PATCH v4 17/17] mm/huge_memory: drop the redundant mapping argument of __split_frozen_folio 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: <20260908-swap-thp-cleanup-v4-17-b532a3f20e71@tencent.com> References: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> In-Reply-To: <20260908-swap-thp-cleanup-v4-0-b532a3f20e71@tencent.com> To: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Lance Yang , Usama Arif , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Chris Li , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Youngjun Park , Yeoreum Yun , "Kiryl Shutsemau (Meta)" , Shivam Kalra , Kairui Song , Kairui Song X-Mailer: b4 0.16.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788804732; l=2734; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=vXuKEkPerU0mVuyMXFabT1MLxtzu5nqSMfp99jol81c=; b=3aA2jvBV2hPX09DX5zvAVmx/EHcJ3O6BlLizYXiIsnWUZ+jlp7qpv7EedEDJW5NntP7knvECk 8I+n6jWz3rkDRLxVROakXQpH3rAis/tqHiQvJPb9ETi64L45JeNJre8 X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= X-Endpoint-Received: by B4 Relay for kasong@tencent.com/kasong-sign-tencent with auth_id=562 X-Original-From: Kairui Song Reply-To: kasong@tencent.com From: Kairui Song The mapping parameter only served as a non-NULL check to detect whether page cache entries need updating. The xa_state pointer conveys exactly the same information: the anon split helper passes NULL and the file split helper passes &xas, which is non-NULL iff the folio is in the page cache. Use the xas pointer instead and drop the parameter, along with its kerneldoc entry. Reviewed-by: Zi Yan Reviewed-by: Yeoreum Yun Signed-off-by: Kairui Song Reviewed-by: Kiryl Shutsemau (Meta) --- mm/huge_memory.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 661b1c747c33..c98756bcc5ec 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3825,7 +3825,6 @@ static void __split_folio_to_order(struct folio *foli= o, int old_order, * @split_at: in buddy allocator like split, the folio containing @split_at * will be split until its order becomes @new_order. * @xas: xa_state pointing to folio->mapping->i_pages and locked by caller - * @mapping: @folio->mapping * @split_type: if the split is uniform or not (buddy allocator like split) * * @@ -3858,7 +3857,7 @@ static void __split_folio_to_order(struct folio *foli= o, int old_order, */ static int __split_frozen_folio(struct folio *folio, int new_order, struct page *split_at, struct xa_state *xas, - struct address_space *mapping, enum split_type split_type) + enum split_type split_type) { const bool is_anon =3D folio_test_anon(folio); int old_order =3D folio_order(folio); @@ -3882,7 +3881,7 @@ static int __split_frozen_folio(struct folio *folio, = int new_order, if (is_anon && split_order =3D=3D 1) continue; =20 - if (mapping) { + if (xas) { /* * uniform split has xas_split_alloc() called before * irq is disabled to allocate enough memory, whereas @@ -4060,8 +4059,7 @@ static int __folio_freeze_split_anon(struct folio *fo= lio, if (do_lru) lruvec =3D folio_lruvec_lock(folio); =20 - ret =3D __split_frozen_folio(folio, new_order, split_at, NULL, - NULL, split_type); + ret =3D __split_frozen_folio(folio, new_order, split_at, NULL, split_type= ); =20 /* * Unfreeze the after-split folios and put them back to the right @@ -4197,8 +4195,7 @@ static int __folio_freeze_split_file(struct folio *fo= lio, =20 /* lock lru list/PageCompound, ref frozen by page_ref_freeze */ lruvec =3D folio_lruvec_lock(folio); - ret =3D __split_frozen_folio(folio, new_order, split_at, &xas, - mapping, split_type); + ret =3D __split_frozen_folio(folio, new_order, split_at, &xas, split_type= ); =20 /* * Unfreeze after-split folios and put them back to the right --=20 2.55.0