From nobody Fri Sep 25 09:21:17 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 F27BF492525 for ; Mon, 14 Sep 2026 17:15:53 +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=1789406154; cv=none; b=oi1CJKOnAGSyOD3bnBwhT9Rx6+L+VjnrReiAlSW37lodf+WiPwFKhnDb31gTF2+0zj5a+KsPvWqpCmskDA+Wa5Ovy89LhwNEhjbbeQfeiLSXpja3hXhn/aWPJ824OW8Oq9FDkmHJZD0XzJv4SC8k4oBE3RwHTXkiuqvaEQjLNZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=q6d8QZgJ9uVNO04KnNDgtygNJ+rHQadMULxGSKbRmEg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ce84HSFUGPCHNZdDTuBg/KeZO1ra7VWywWEV5S5UEZ6KymttGJlDRUKncmasdveVfT08ItolF1lFzL3+FTCH83FkrgtZxlv+BnI5T/8E+SrqXlZ7c1DQx5aFkBrJ/NQgwomkXOU7/cG6wHRxpn4IryscZE0hEdOtLQQbLHgp5lg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tcpLb9kJ; 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="tcpLb9kJ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 8D584C2BCFA; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406153; bh=q6d8QZgJ9uVNO04KnNDgtygNJ+rHQadMULxGSKbRmEg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=tcpLb9kJ28FmtFy5JvuCEPC70mkaGA2lAAjhkmF/9Tlt3B1ayNzdO4vEGsKbw4YYn W5A4zIzLNVFskozAy/YG7oXBY4F6J/ZCzXrSIstlEQG4oDjNX+fK7EvV9VyjT5DbI+ gQjnQ8DOFl/QsSkmInplsH3yi/e6P2og2I+kPCEPaqF99iUj/IgPAR8B5Xr7ctZy5A dx3BwwY6a7IUarqJ6uEg1hmMiulpY7AQL/6I36S9/GkIhet8VTjKABGVA4v8z3Qt/q GzctZozrOQoE+NWg/nelfTLd6vf1IDT4wnV/l1Cf/kc5lZJftN/UzWf/lLuQ6UO8gk swSb3dMadgS5Q== 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 6B20FC88E72; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:42 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-1-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=1650; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=810n4do4aOKMWihCxqnhsHXg2hcES1SAm+rRly1NOZc=; b=TD7AokuIIIO3qHuTryNrrJFaeotme90f+Sx8e3cBvBRNKxx+8aj6JZLK5qKRH21lcwrMz1ac5 Z6Yn5pDcF3EAmvXXtvcBrZhV529Cqpzegiilz1N9cpCkU/1k+pvbA9g 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 625c185a1ca4..cef44aadee61 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -396,8 +396,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 09:21:17 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 F25BD4825B2 for ; Mon, 14 Sep 2026 17:15:53 +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=1789406154; cv=none; b=TQ1KbL0d2sDAywhw1ifpjrewFHhUvXkXfZCAX26AdCAjsHGo/LzEZ9v2G6bIAs33gJUyzzckyuBJ5GSMNAN5w8oFa0mxsE7QPHxZ/yu8TiBACQysA6A+gZyqKnzyWLuWz+sL95tYeoeAo871wZaUtLxYhwiPtv90e0hatT7r2Cc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=tmqSHbyI6Xb4v64GvXcWWq54HgIvyBGsHeSU+Ycg1js=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lXCQwaf9QGAbrcSPWKDlEM9xSXP7Ev9OPIVEpcfrzTBgVqmg3mwaKhxaKr+G0o0vQXHeWrLz0VZkXLIS22HeMoiZwYbMsp9LMlNMTBunnSbQwFumeva4hWUDj75IyTxJam5x3xPhA8gm/7zkaCAJqfhSCLfi3swIVpu7YIY9kvk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jWGpCUfE; 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="jWGpCUfE" Received: by smtp.kernel.org (Postfix) with ESMTPS id A9D43C2BD00; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406153; bh=tmqSHbyI6Xb4v64GvXcWWq54HgIvyBGsHeSU+Ycg1js=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=jWGpCUfEg/3UkU4Gw2pwweRoRvr07L+ns78LHjMYp5ds2kWOttIDRVL9RVQiBi6+8 Qwu9B6wA3gODhk9iEUYBqzSF3ZNMOTzxaEFPnfZdUnalksoKKoViBni33OssQLTRtE SOjZKhUaGeMusBEcuQzDMD64R+Ik3uS0MW6e1nm9jY/0OeItiIkrZI/64qoylbVM7V nGUStS18P9LrySYwxaEXugAQmxRfmfPATcVPcbsZEYct2AWZqEDeBaQYEeBCP9WBwZ SlZm9ETDyQJyBQ+InxRiGN8Z/uAW8YvOt5iaScWhi7KJbDHOxwLEOwDdV4gIGQDgj2 73DXIyC6B1ZHA== 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 8C3CAC88E78; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:43 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-2-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=3844; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=os8GAwRhiIAeYozzDiYE5/qpjgUr240Y6fX1iEFFm7o=; b=x/Xr68PDIC2GidVJPvhZOkF4fMPuURDvqo9AMcQPkTXq+N/nZXOj+Qides9OL/uE6BsYnEoi0 yp8AJJq1p7ZCESo/T6+fI8f/sEtTrNCP8wjue0YaiDEN6vRXpRmwBni 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 7140a1031fb2..351e8893808b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3934,6 +3934,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 @@ -3942,11 +3945,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 /* @@ -3957,7 +3960,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)) @@ -3966,6 +3969,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 @@ -4038,14 +4050,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 09:21:17 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 F266D48A2C7 for ; Mon, 14 Sep 2026 17:15:53 +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=1789406154; cv=none; b=oQ8jk3eam/YY6o6OmlLyxWdH4UhlWAyPkjLHKAWJAE/fYCbPCB5NClk/euHhgo29IbE+UVZVApBE+PBaS2L4s9hpzTwbncH5e+gI8Q5Hew2vQn81WMLzxv1+187EMIa/jsW1DqKcUtxrIZOFyohxYzX8/SbX76eP+BADLSKpDmk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=fyBCOw4+N6CRo45dsKGNLKOnvaUBAl4lgh7oeWdQpuo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MHPIffKz1qjPFxBDhubaL5YmUUvBve8gcuqi0AEfIBq4SDM4tvemT86eWmY9tQRuc6UHzAKgEIEznM5JIqXHZab1a3QbLkDmL27WKmNqOHt1DLJCaVUaudu7wUwvgmT5cG6rIaT6ZOZ0N/4FhKeOMBE8WpqPpEYDauiCnEcdfXk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eehZ0h6D; 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="eehZ0h6D" Received: by smtp.kernel.org (Postfix) with ESMTPS id B60B0C2BD05; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406153; bh=fyBCOw4+N6CRo45dsKGNLKOnvaUBAl4lgh7oeWdQpuo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=eehZ0h6DOvyjU1/3kO9RerxTBct+MQyAmnzRhu7M1/XVHwv1NoXrXhFEay6wtDcru IeiGJQHYa/GYgMWJcTd4c5M/INUkfirmGXGh8qWmhWziKcEnwOx3QzRpLwotC5jmLl LOJIVtwWOu0SMF6ujv3H0R4+C/JvWeNNBfN4oRvtuJyQnLHusJte3tX9ukeuwgWqVL BTQ86klkkZ2HR2rItVWstOBVo2+20shiUw+bWLplc+4BVlqfkyu005PM1WNqCuJ3bh T9K5/jJNnO/wv8xEgmg/Zu7+ErpZIBWZKpn61BXWWj0HnK4XYrbRFqFvcleeroHces 3kW9xdjJpb5HA== 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 A3750C88E73; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:44 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-3-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=7784; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=latEh40NnLWKMC/lwPwKkp8cUPKuNcUqCBFdrRonmI0=; b=LF9CwRSWO7QX2xtJGgU1N4DjLMpt/6TJD1KiYIIf+U42yUy3OysnwhHcRc57vnLNCfDKbmIVF qylApHUe87EDjJNSFbPiCuD9raUQcmt76Qt9iylVNZ5/ho0tDpXFTm7 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 | 178 +++++++++++++++++++++++++++------------------------= ---- 1 file changed, 88 insertions(+), 90 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 351e8893808b..d9f0a3a9c9a4 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4015,121 +4015,119 @@ 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; + 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. - */ - folio_reset_partially_mapped(folio); + /* + * 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. + */ + folio_reset_partially_mapped(folio); =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 09:21:17 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 3BC014963CD for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=FF9EuYdivn/okk6OlMU2puXalvnGvf9QnujNPbYffGh3hKAyWRV2c2YPjMNcPlfU+X4/oJ58b5pdXD5nsGEz21iVEh2Ba7T+Mu4StT+8Z9jEsgUMA9QLIfXQ7crJTboZ7/gu9GqwDwL7qVUYGsdqXFafp1H/u3nXzuj+fOq1nGI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=vpyZblKSFZcYpGwTTPPtcEZT8s+XgHlHmn55xd/8CW4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nEzN7uPxuuCuwHSt2F8MtDXVpmX7Txs6iFrut++aZUGjKiVrU6/aOH+tEld/mXrcoyP1ycuCL1Cic0dw8ZlW8KzwGUROWPEGL/gtQKhJVyvRjpqUvCbDfCh8SrnPwA9wLc/rztQNH/Y+0T4k3zYNRg7RGlUKaotvrBTY3tg5Yxw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rAgQrPY9; 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="rAgQrPY9" Received: by smtp.kernel.org (Postfix) with ESMTPS id D11A2C2BCF6; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406153; bh=vpyZblKSFZcYpGwTTPPtcEZT8s+XgHlHmn55xd/8CW4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=rAgQrPY9b7KzVDsWwJI4ziWol4HParHPS4y9vwdSCihm1kMza2Zl9ulLDliunnAjg 8nDKGTKeBFZaYQDyh4xInTnjDu5X2iYyphBWr3rpyxAQLVgjCrPQw1JVYm5fvv90S/ 92re7LYTFw9N4tGcxsruC6VwY2x6M9sO90/cAJOS27yyLeqtUhSUSVUQberZ2sp05C SE/iQu759p6JaQT1bH1F5GxNlauyR7jZZ7JHmSNUhfOFznt4vUrdNlfnucsd804CDC jMj8fTYHt1xj6beJCA8BrVXuPgMbw4woThrDggRQtIKc77rzEC8TwXkuJEXiFbBmHi zGDi0zKhYOtDA== 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 BB0C6C88E79; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:45 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-4-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=8306; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=EZ5MURXDy479u0ESyArci3PKv7DgHL+vK2nAXaF0YN0=; b=tmEOzcYQh7BUs4kNys1LPKuPqL2RLWN/VVlqB9tO5zhyrCaqRHF2zHgg4zGrvgAmTcyCOEIGq tb2lzyWLRULAc3kv5MEDS63Tvld8dkvaB8nAD3GVLaK0KWKzqFfEAcK 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 Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- mm/huge_memory.c | 124 ++++++++++++++++++++++++++++++++++-----------------= ---- 1 file changed, 78 insertions(+), 46 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index d9f0a3a9c9a4..517259c1c26f 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4008,11 +4008,9 @@ static void folio_reset_partially_mapped(struct foli= o *folio) MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1); } =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; @@ -4020,8 +4018,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 @@ -4036,24 +4032,75 @@ static int __folio_freeze_and_split_unmapped(struct= folio *folio, unsigned int n */ folio_reset_partially_mapped(folio); =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); @@ -4063,7 +4110,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 @@ -4073,29 +4120,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, @@ -4114,7 +4147,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. @@ -4126,9 +4158,6 @@ static int __folio_freeze_and_split_unmapped(struct f= olio *folio, unsigned int n if (do_lru) lruvec_unlock(lruvec); =20 - if (ci) - swap_cluster_unlock(ci); - return ret; } =20 @@ -4270,7 +4299,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. @@ -4281,10 +4313,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); @@ -4384,9 +4417,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 09:21:17 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 5A9A74963D1 for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=eSyDlFI36SPeNVZecILWF7V2IlXfVKo8wraqSzFKgOjxrgppyfNCsqJi/2VMsQmWy6IyizaJ83xIguI45Kcn4aJDjP1lNF/Fu6rQU8lf+A33bWc1J4Kz4p1MBabXYutT2Lp6QMKtEqZS+NL1t+njAqbTD1H3Ji6Tufm5Tm8RGFk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=abpVLnEUvW8CDt+a/XpJOaH91FoTKNqN5452UmC7Kt0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sEUnATCATg3ynzEnMXlopfHIZyBWCHeJUIB8VtxDPmG37oiOvRVngFR6vLMcUU019aP+EP/FI2pkiooYmUjMAUwTFpO0ejXTercKkO4zahkdyOgXExeyjz3G0WhsxybB8RWvugtBmsfv0a2VTLlaQjZ37WwBQsjk5SyTtFK8Ye0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dOtXpksE; 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="dOtXpksE" Received: by smtp.kernel.org (Postfix) with ESMTPS id E8036C2BCFC; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=abpVLnEUvW8CDt+a/XpJOaH91FoTKNqN5452UmC7Kt0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=dOtXpksErd5xAnDA6AYXoCVmUeDMbQwQGeEBd9PzfnwA8/lq8pROdzzVvYtBGmUJ6 SJEkulF8f5S6rp1eRKhK1SoQIwxbZ4qNNCQEP4Jwe7WViN8Zgcv/4WbROf5lI04BRt uIk0FZ8eAwd6ZhjCssMfc3vo9CChWEtSMtKO+z0neqw/KtlQz5CNHybLNjTjjWgUCG T4nXAG0uqV83W8pwcHDWgGzaNd4bcquLtilLf2EbvDc5y3DiwgfRiUtOOs/md3FTEV 1hnF92LUhQqJwaOe6ttRVrfNCeD60lZw6SuqhI0rmBGkM30hTAQJF47opHk7wMNq2V Z94aPtIfSDuGw== 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 D0E7CC88E72; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:46 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-5-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=4280; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=XND1MzFZ/5QjlCiHq1qzBj5rRVTZjMI69ArS+Pfup4k=; b=eP2IZf1y9TDMHsbAuUXluphK/piRi22XAPlid351B6F/CMR45W/DuZMohILXkvr8o7q0az7ji 2tNq+Mm4wOcApIHDphbZdHS9tJzYNlRPJi4/cN9EO/Kl9iQFDnQW8Kh 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) Acked-by: David Hildenbrand (Arm) Signed-off-by: Kairui Song --- 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 517259c1c26f..35c48eaf038f 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3811,8 +3811,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 @@ -3851,7 +3851,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) { @@ -3861,6 +3861,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. @@ -4038,8 +4041,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 @@ -4105,8 +4108,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 @@ -4170,9 +4173,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: @@ -4275,7 +4278,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 09:21:17 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 3BCA54963CE for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=Sp1P7hvv/Ej3cxYeHbWzDGxt0hZWxvT7p2yfbY2CGuRCBB0in9BL6XrpY4zLB449lQjhIkUZllIIiWVOudewMnHIUnJ9Gu0K/kh9hZUwJlr+ZkP74D6j2LoOr+zKIMW6esiIilIl+ugf8PTRcz3R3HQc3DWShrT+DTiTsrn9lww= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=sKZDHoz+RJ+OQK9FQGfaH8WBjdnFCdhcSJKgZrGIdmI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ut22kkuC0IHvG1C3QF4wv1LRUoswJ9OHmlQZqNE+dQ3TUW+E7bJqxC3d9Jfc10gL8AfX07npdsjZkfWcd7Lrp9NyYyatgp4YOZnZnmNKDURAU0jfT9Sxvb0qDnAtYhKe+soZPLo+eic06vKwo5FIzb52Qd1E0VEZDnqXmooVSRc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JByXqX0q; 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="JByXqX0q" Received: by smtp.kernel.org (Postfix) with ESMTPS id 06E07C2BCFB; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=sKZDHoz+RJ+OQK9FQGfaH8WBjdnFCdhcSJKgZrGIdmI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=JByXqX0q1j26XX2lDvOpIH0Jm5gVey8pDRqt4XSl1DQFUmeOZSdQ2TuiQ+CGWcpk3 J5hwpSeCfkI0hpiXzU1KjX0RNxSdIpHTFsrVh9zhkzalsY11iz2Mt0Hx+YpiBqFhzp ve5BRisXHzo01mQaHxAp0AKk9juJVh04MkLGvweISMIFe9dwlW3+QyzT5Xg8V9ft3r AKwbxdGYIHLKE3tXPRsPZqaWeNAPKqMmcS38Cr8FiKNR5t2VXZ1Lfb1spvR8yMtcQj ettM/u3220dM0ySii+u2liQY1Dmjow/AKrYd0KqSRGFZYxLy16EwluTVFC5JOgYpXB tPzmTNy5nLurQ== 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 E766EC88E6F; Mon, 14 Sep 2026 17:15:53 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:47 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-6-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=4898; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=9nADEDAf7Q9o9bXChgiHRbBnW7jE6WqRyVFeq9s3Ky0=; b=03mBbAMWRAHMpV7mScz8iM+udOGiUuGVdjnxWdWseAaIHfdPl7Iv3bMw/akl6nNTGxkjw4FWx TwBHbqINGedCi2EC3lsm3zWPq7OC7McZmGyyaBUcB4nwGRvpu8c9i3p 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 Acked-by: David Hildenbrand (Arm) Signed-off-by: Kairui Song --- 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 35c48eaf038f..d0e2f1801d6f 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4021,8 +4021,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); @@ -4070,6 +4074,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; } @@ -4088,8 +4093,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) { @@ -4161,6 +4179,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 @@ -4300,32 +4320,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); @@ -4409,8 +4410,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); @@ -4419,11 +4418,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 09:21:17 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 6A12A496D36 for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=V6hGz9xAD6txz5f5fffR/yRUXP8w1d3kmUv6Zq3iIq4wy+Gi371ZkBgrOd/WEqby3HwlmLz8QIyZ3VbC7Hwt7AWkSUZ+kUMJVpnmceyyEbvSXO0pb7HGl7ykpSD7WhlM42lk0Fep3VTb9krGhVN32WS65IZpbfuuCuHjH+5cXRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=XXmFu8FHxp+9q0wq8evTBl08FOOinwleYwb02Vqvh8c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=vCG/MNkuT6E53/sLxpxHZ3cmcokNZcwJbtfZ+6SaBKn6dbP9oll9JojH3v26o0QrBesrR9UiDuvuRhTEIvcFtUTheDWg/Qh05PyuTfhFFUw/QM2c2EH45RygZifxWzhqYo/W5xOdQcoSaRyMHZpPLFYiYYsRZ4G+DDweYQZ5D6M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Hau6a+Ux; 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="Hau6a+Ux" Received: by smtp.kernel.org (Postfix) with ESMTPS id 1BC3FC2BCFF; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=XXmFu8FHxp+9q0wq8evTBl08FOOinwleYwb02Vqvh8c=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Hau6a+UxEHuh7Utut+giSkDOd/tl6AStxx++hPJqNL3YyNLC9NVRWGGboJoqUkZ33 Lv3cm8vTFMTyLZgOMns5//blIRuxsmM9f0MUvQXMKqeyb4AAIPlIIrCJsM6ZYjsJyG XXlWxQsfM3uRLTPtIRLswK3dXDhE1GewK5OwfGETMw5bjTjuElSYhnvqsJlHOVuZM5 ElKEEYOp8kgif894YCujkdPD8SL+6zqshKEVr01E5kPbocTqgZtqNLsofa80Ysxzo6 MroXN+7I4xyaatuRdc+z5IyLW2oku/vjQuhBX1XmZJjvt8SZyPxCINRWP0tIDIP3ip NZPCnjh4Et7kA== 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 09F79C88E73; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:48 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-7-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=4114; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=Ts7bWTM2eMacGjQUWD5NIu7YG58EfZYRRZU/elImP5I=; b=vrfo2CDuxED+xLqydKpyoRBo7l5Fjn42gdwXH3C3ECxIr3CfRa3G1kpC+7HTZ8AW5SaXirZ3j z03Qj9W9sWSDi5TLZB7e8xwv+WCGq66Nfl5ni651f8fOrmh8l9KIfFp 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 d0e2f1801d6f..5ba3bcdfc42d 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4083,16 +4083,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 /* @@ -4157,10 +4170,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)); @@ -4181,6 +4193,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 @@ -4217,9 +4231,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); @@ -4296,17 +4308,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 /* @@ -4325,11 +4326,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 09:21:17 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 76A9F4582CA for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=leiStNL5CMZN8J8o76JRfMirsmWJoW48jUnpdyZaZeSh3yCTUzTGpyYsP9hItgg1eNJZeKZ9Z94Tk5gM5/4GhRKAfFEimBulKlxuPOWBia7Y5HB+Pd0dv5pRJFi66c2o0eTWgasCTT4UgZBHV+mTj+Pc/8qXiXAvlSfRIaxgxzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=QtZr5PnzpwtK3QMP+hirTKj5BWjg8s77EwEdpYTWNpw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qvwprS5w0UkU7SQLPeL1VLqCvNWx7A3WTHekm0tJD6zB3jLFZ1KPZhdy2NpELEybTjMNd3PQbCrlyQVplvrooucYqzcUw2YrRZL0oNwe+iFGRHCUVJDobPv5OgVkk36n9eG7wbSt1bZFo2/ZOs6Oy9rJ8taq32mKDqcTQ8HGzRo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FcwlezMF; 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="FcwlezMF" Received: by smtp.kernel.org (Postfix) with ESMTPS id 32150C2BCB8; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=QtZr5PnzpwtK3QMP+hirTKj5BWjg8s77EwEdpYTWNpw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FcwlezMF8xsDt0tIYvhPwruzAp2WOjlDRU5FMG2DvTxwef1Iaw6adY4BkcOlXcdvm d8VYjZ4rBl8uhoasBlJJD3Y8uUKQrsv4RBit/yYjP47hFtl1kaCALsiOtDw15vf9ul LFShhqUSB9nPhALhJ+Y7Y+cm/l/PrexG74Etx56yVCwYFVAn2tp3p2+W26TiqyzXxG xdakkBZ/DbWIdrDZk9uteCnX8SKYU5n8gNY9H7Xy5/iaSDKnWNUJH8swWRT2K6ezrG 3wMBGSqiP5yJ3JIAbk4y63ooORdTsiUE050OPNqNmiDMFbd8m+AEQ0KMnRhEO2GFbw LAjIXcvywuAcw== 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 1DC8DC88E78; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:49 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-8-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=3825; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=1AepHMPhtQhcirQKIFtuSgKsIjuLHdIJpzp6kOWU4PE=; b=lHpDt8hux/TpdAKSrD8AgwYlgPrsCYAm5NsJFwkw3s3EQTUfy23K+R3Bagt1JACVz0WPUWYCl mtOhIVUKypvCswC3oDduF78iBvKXj35nfiqHt6wz3f91m+WWyjS1goI 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 Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song Acked-by: David Hildenbrand (Arm) --- mm/huge_memory.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 5ba3bcdfc42d..1749905ade6a 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3641,9 +3641,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); @@ -4017,15 +4014,23 @@ static int __folio_freeze_split_anon(struct folio *= folio, { struct folio *end_folio =3D folio_next(folio); struct swap_cluster_info *ci =3D NULL; + int old_order =3D folio_order(folio); struct folio *new_folio, *next; + 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 */ @@ -4074,7 +4079,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; } @@ -4106,6 +4117,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 /* @@ -4190,8 +4203,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); @@ -4231,7 +4247,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); @@ -4319,8 +4334,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); @@ -4328,11 +4341,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 09:21:17 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 65E58496D25 for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=pyN8eeR2v2o9wuGLH5bKxXzANQSONWGdorO0sHwJzGvG6dX/ZmP5oD/mNd9CG94U02OrxjChsT4Ex9VmYwnW9HOzphZSw9jq0VJn2Z1ZXFyn7xKcN8LsYuh/NkXQGhEeOHRgaIk/WKhb+fHS4W5G20Ask9kFVbZ7nMZ+QvVNr7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=DcJOrA+hy4AdWGH1eeNmetKcf0DNfdUW2VhTqnlEoAU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rGvwN28O/xd0SSWOB+OuOMXFwXdw/g7GXkXl8aCSd+V5ycYex8oXIL2Y7HCfkCorfY5PXbi/O2Qi/p0KdATukcHjyfGF55cnzBVcXyv2dI1pJLEY4GlAZc/hq7cpdEFrymTwp6VzxDyX2oN6Y7IMCGG+6o31U5n+ZEkPYWGU6vE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ed7ob6Bd; 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="Ed7ob6Bd" Received: by smtp.kernel.org (Postfix) with ESMTPS id 4558FC2BCFA; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=DcJOrA+hy4AdWGH1eeNmetKcf0DNfdUW2VhTqnlEoAU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Ed7ob6BdrjtG37mDev4F19RRa2aPP/yEYcOoqVcUtJFXct6gd/F9OgEOA4GtBjruu RTTXyGCSQpmzCPTTyoF3zk58iiA5IgvFq4gJR2MjTjon9nW85Ro8QfSR945EgoVCLr f6koUwzwNabGoj/8uucvuHcV8KqTiuZ+pAbwBZOg6bScPBlltTHkC5dDn7M8vfzDGv /4Ar+DvC4SzzYKnhTIHwmT9gq/mxKMH07ro8udr+CqgmriK9yu1nEiQ1ldtLs+xRbT j8NycgUs9CxHlq744VdLReq4jMvqa/+qC+YKTRiLmIOm3sC8jmaikHDUARj3u6IGlJ cTniMJRPJe9Hg== 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 33B0BC88E79; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:50 +0800 Subject: [PATCH v5 09/17] mm/huge_memory: rename remap_page() to remap_anon_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: <20260915-swap-thp-cleanup-v5-9-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=3127; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=ExS3iXqpo6EWOs0c9NJj+fgN8aW+sshu/TIwyTi4/5Q=; b=Y9+nNMHYhV9nhxAXbvADVASdUNcBZtc1OtdH8YWUKSGPhLNd8GhGs8EA+UdTwNypv2ZjEdP5e kG/KWg5Q5svCci6svRnAHXzSF2FUH7jMNCkRnQrjceueAUdlJWjA0yO 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(), and is only ever called for anon folios: unmap_folio() currently leaves file folios unmapped after the split, so they need no remapping. Rename it to remap_anon_folio() to make that explicit, and add a VM_WARN_ON_FOLIO() documenting it. Reviewed-by: Zi Yan Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun --- 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 1749905ade6a..77bf68c9b9af 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3552,7 +3552,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_anon_folio(). */ if (folio_test_anon(folio)) try_to_migrate(folio, ttu_flags); @@ -3637,10 +3637,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_anon_folio(struct folio *folio, unsigned long nr, int fl= ags) { 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); @@ -3724,7 +3731,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_anon_folio() will restor= e 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. @@ -4084,7 +4091,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_anon_folio(folio, 1 << old_order, ttu_flags); } =20 return ret; @@ -4206,7 +4213,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_anon_folio() and adapt it. */ xas_unlock_irq(xas); if (nr_shmem_dropped) --=20 2.55.0 From nobody Fri Sep 25 09:21:17 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 83E3F496D3F for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=RmRTlcHo43O8fX1qtagH57rZFO5yLZnRmkFkWV/hVlsD5A3UqhfTrmIfCEn1exiPNesm+GGozvoUbmsgXFzqm4iph40cadaO3HLC6rcNj5rZ0HiuHcf41x/v00swI7HsPIveeD1JaRucnTgnsrfbEnG/rav5VZOqzy8zpoL/8eg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=K/oSF+2agPXDgDxaM2IzKlARsF2Hh00l3yfgiAnAguI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j983ssHGfD45HnwP1w56LhQDFJRVn9sfApidND/sNiLd2pTlVb5iWKUb0v4iTmXihuTHsf5+PF5cDO84q7kNWtFDP8UIlkAUF2ri5LMHSjDnyDq5ccMy1Jv9sg9BuHwEVcq8RDsO/9M0fumCYuMwWop2gGkBF+IT8Hp1BqYJlrk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZzPJ/z0v; 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="ZzPJ/z0v" Received: by smtp.kernel.org (Postfix) with ESMTPS id 65DCEC2BCF6; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=K/oSF+2agPXDgDxaM2IzKlARsF2Hh00l3yfgiAnAguI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=ZzPJ/z0v8Qaoh+5nn6E0vIqhApfn3qV77JPI1JxIf6Vi3ZNzO7jO/pKRh+t3IIw+d sWLlp8VWopgI+mOHhDoTbuhA1lxFUPZ2rYkX/JFHmXXo4ou5yMPz09jI3BAUz7a5Nm Vkb1h4yIXBzaMvhTVEz3qfqzICZXZLnGJjSrg1x+hBGphtLKdm8ssW4fvbMvnwmnrg hRdHdvcyoyDCSd8JnbPgdP1f/W6ZkNxd1iTdgUhm5za3f8i4lTjQzSpbtI5bumY7mb bg3Ya2luMcvirCqtvim78d7anAkbFehTJI6cNPzJfywbuNx+KbD2qz1Lr3B0DDHbch 6xm99bhk02CIg== 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 528A3C88E73; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:51 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-10-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=3481; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=6TD9CYMGDYoBQJQWdao35dtOQRgVegEwGFMbqhcYaO0=; b=lVGM00QcXpp6HveeRp+JBlSlB+2SK6QZpSYox3k/Ndb9lJ/6B6bASgXEZFd2PRyltk2PVjluZ Cv5U5EOzV+OB17/C84FB5+qsjW6nu9RlQipZ6PwX+sJzGCuJVmsoRVg 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. Reviewed-by: Zi Yan Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun --- 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 77bf68c9b9af..859aefda7356 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3539,13 +3539,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 @@ -3560,6 +3564,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, @@ -4030,7 +4036,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(); @@ -4124,7 +4132,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 @@ -4332,15 +4342,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); @@ -4379,7 +4380,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); @@ -4427,9 +4427,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 09:21:17 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 9F8C8496D4B for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=ekXN08JeQ5FUH3qkUm8NHcB80S9fIG+4WP2tsYnrBXtR1fGXg2umSt45rDJu0W8U3ZC/KjzHji/vfGJ7rqcZbbKTt1CCOIM/MOUxnvwpSBSIbYfHhywBG5xD0HpKkUlVMUGL01rwgfvnqE4erWoG8ghvuvTiAOzNIQRKMaCTNs8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=yN6dSbWHE1mq+6AVew9g9RLNAHqkaYJzr7RZ74KIHWo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ss3x+ja3d5t3FhjcJjEKNTFhyODCsMIqZtVEHghY7Z216nxrQA0rG0XEb8f3hV7RSpy+IspNZ0Jcm0fVdsZLg3WLKk3TV5ggEvRQuUQ4W26yDnIpURL3/G+dD/ZpvNZEkC88DVVE56wD+qgXP24c5dfWdVPhz5SPlc2KyQEJdGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BgyaUWBU; 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="BgyaUWBU" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7E3F6C2BCFB; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=yN6dSbWHE1mq+6AVew9g9RLNAHqkaYJzr7RZ74KIHWo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=BgyaUWBUP86nLCNiNciq6K/phtuBazyZNdD6+N2ox5BLie1vmKl3ECE/M/7c9+CyX wt6u5nKB1/5ZGkFs0M4WbVD8PRi6LhyiYwa3xTJCTGfsm2Ql4Ecre/hv04MAlvFe4M WFX3F5qTKZ2ut7pWeMPpnl/PbBkn6xdophtZDXmwp1KOe49JBV+mGh7XGiCe8r9umX 3pTHRwvpr8GtEsUrwezM4sT8UF81I2zQRIzMhI2DeMPLoO4P9PISGmL1webu5/KQ0X dytPmriYcWS+gL2SGwmXN/l6zWqHfaQVxK1KkTGPUs6LMCTB/vidqpe+lYQ10EA2TO eu1T2qjI1VLEA== 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 6DAFCC88E6F; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:52 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-11-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=6352; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=jPIK+D3oCGVmQgxmsX24DYG8DueEazRAgatVriCZ6wc=; b=WJUYaKVqz07jR4vA2mKc6OCjjrfi2Q7DWoeZWfhvoJqEKCgcle1kHNOi80K4B9fZEsJL42ec4 nuKP6Urqqh4D0Lbc377xZs+MiL6mIQiqCKMl5+R1EnzmNMgcfg1bOp9 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. Reviewed-by: Zi Yan Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun --- 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 859aefda7356..8fc1dd5b8354 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4107,16 +4107,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); @@ -4134,15 +4160,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; } @@ -4169,7 +4195,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 /* @@ -4225,9 +4251,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_anon_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 @@ -4256,11 +4292,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; @@ -4307,60 +4341,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. @@ -4384,14 +4373,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 09:21:17 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 BE4C8496D59 for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=caHWAx9eNyXow2fBZF+macKJC7NJPuPB9GtY6W0EezoyILiGpj9vHtuRyvxheuEd2e6hUu11G4aLf4LBPqkHZTuJLlNsp7IpOppkx8DHXgrLa6I9s4ly+j1XqFCbFOKFhj4mA8MjY96Zo9/PNfxKQP9NtGtSpRFCWOO/5cPxuwc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=5CNc4rR/d/ayE3OXIw+55X5cvbIF2S13xm4vRPvnuRg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KpPo3lK40RwCEKTGN/x6sjw7AKg4bDSUNg1Fdum0+Zt2ZQuHTeFUM37KwwTbZgrh/koBdZ1mTrtmdzqCrSWV/fkLxELmpd3o+G6Lao8lCt2Vg97kkQrq4+2Yomnn2X3E9Xzqedtzt7i54Wblgy6ppIsdBVXYElONh1vyH/F1GqI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ispodhHp; 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="ispodhHp" Received: by smtp.kernel.org (Postfix) with ESMTPS id A0517C2BCFC; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=5CNc4rR/d/ayE3OXIw+55X5cvbIF2S13xm4vRPvnuRg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=ispodhHpTVtBhqvKEMp/TbPogA/+Xfn99xJR+fwHUZnrb+D5bDBASkB0PKdwxHNGv 0Q5qzzcEhjqcndZUxfGwiXeyTuTuPygnQSDNme1GdLe6j/OWK2W/GgkYUDURItxtqi zzOrAjJ4HHCdQic36R8sjsjpBpw1lBglKCqRD7qGIxDetiyUDLxkLNmg0zvLJ06uiR NvAweatRntvDtQQG4mpZQbpp36dS06wDG4OqZAMBWSSiwNT1bVZ2jv2+Q1FFF/kFTb 9V8FATxGiGy3M81jDpsyjxHSlYQcCwODu6+eayGwchR6Iddtzsv6MisHoi4beJsjTP zUo/XgR8+uFKg== 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 8F00EC88E72; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:53 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-12-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=5796; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=bKr9eovHFefL9hi9tubKoHjBzPEs3edNnMMyZanSRW8=; b=C0vUEdDIAdaS6RGWbkKTPC9cha7NRzG4/Bvy54IXTYpY+Hw2UGkCwgHGGoLCRywIxUbOdKKED si1gFwiTiOADbx/CvUmVkZO0GnOz/+4TJgFoko/hoQcUhJJfaCbJf63 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. A 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. - A !folio_mapped() folio cannot become mapped meanwhile: mapping it requires the folio lock. 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 referenced until it. Reviewed-by: Zi Yan Signed-off-by: Kairui Song Acked-by: David Hildenbrand (Arm) Reviewed-by: Yeoreum Yun --- mm/huge_memory.c | 58 ++++++++++++++++++++++++++++++----------------------= ---- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 8fc1dd5b8354..a4c2e38f4a6d 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4029,16 +4029,38 @@ static int __folio_freeze_split_anon(struct folio *= folio, struct swap_cluster_info *ci =3D NULL; int old_order =3D folio_order(folio); struct folio *new_folio, *next; + 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, so we first take a reference on + * it to prevent it from disappearing, and lock it for write here, + * letting unmap_folio() walk the rmap with TTU_RMAP_LOCKED. + * + * folio_mapped() is not stable here, but it can only change in + * one direction while the folio is locked. The mapcount can drop + * to zero at any time, zap_pte_range() takes no folio lock. It + * cannot go up: swapin, migration and uffd move all lock the folio + * before mapping it, and fork only copies PTEs that already exist. + * + * So if we see the folio mapped, the worst case is an empty rmap + * walk. If we see it unmapped, it stays unmapped and needs neither + * the reference nor the lock. Anything else needs a reference + * first and folio_ref_freeze() below catches it. + * + * 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(); @@ -4096,11 +4118,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_anon_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; } @@ -4295,7 +4322,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; @@ -4326,23 +4352,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); @@ -4369,11 +4378,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 09:21:17 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 D011E496D5C for ; Mon, 14 Sep 2026 17:15:54 +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=1789406154; cv=none; b=dF3wj6R9ZkRpHiTN2eqSMcwoh/b7OaM0sjjimqTTeAgbzEl2Je8YNoRul7gzJVMGls2KHNOLgV3W4rF0DSMhIadNN5EapH5zAdqUgXw15/XT8FO3e7gIfHo+5A2/JLLMs5jMIYvHtpTrbBABF28YDr0n9pVPTgP7SdJi3hDY7g0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406154; c=relaxed/simple; bh=/cN+FBCH4SnvUOXkF/Q8DuRZ83YkXTNFzJp9ZpEBNks=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=f/YbKZTOnL4qFH4hoemp6ZSl2KCDuO0JZZ1zdSJScUXhhVgFPUTghOEtrLJ7pJ8T9zvpLsRHS0tnfPjktvoxfax2KgA+sqU7KOGd8AQsTfHNdrHzSoLorrIjzbZuVoQUj0uSsxnDRV8/AEFW9oLP+od+VzpB2QpYkUjmaYXTGIY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IfXxAFVL; 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="IfXxAFVL" Received: by smtp.kernel.org (Postfix) with ESMTPS id B23FEC2BCB8; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=/cN+FBCH4SnvUOXkF/Q8DuRZ83YkXTNFzJp9ZpEBNks=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=IfXxAFVLtNGRO0IBfGROsaWcVBt/uq1e62lhZhlnYUTN95XMzT9qnwxo/5Q9KtwQi lUAMCDJDa2Dij6wrwt3+BG7J+LGANarcgvlrIvUQQHL5qfIBW+vcSCfG/r5esMMLGy AByMHxAnO0MLi+OMx+Sab4a5AQRNvxtc+WYXS+qujBLErG4UQTZTWdH0TizA1PQL/l Esj6JttQBzsd9YAXAF2Q0n1UuI8DKVSRUWBZDXlk+//okJmTxkm8SxWyE+khZJpjan scv38hCY8PePzHyiWD72It9+fDCTR+WzQUbWNCiWODZP8Oud1eJ8pSAe87ai0I7vMS TCfkIdDquZTZQ== 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 A23E8C88E78; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:54 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-13-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=3709; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=cmwyWDJZVe1UvzzNSicYdeAQ1Ie6761/rX/pYHb2eu4=; b=oOZsXsWV809p10fdYi+5NGL+uJfyRilYaw5kkrwFnSewNLF7giO6F61RSFENYbBJxk0dJI/zE mNb0H2jt/+hC6Jrk10LJOWm+/Tqv9YKH7qc8fIM4brbqWOGk5LJyOFo 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 Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- 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 a4c2e38f4a6d..169832e2a866 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4140,6 +4140,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; @@ -4152,9 +4153,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 @@ -4290,6 +4300,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; } @@ -4321,7 +4334,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; @@ -4331,27 +4343,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); @@ -4378,10 +4383,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 09:21:17 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 E8EB8497B68 for ; Mon, 14 Sep 2026 17:15:54 +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=1789406155; cv=none; b=S+P+cxjQcE1nhHuNNw6Pkknd0Y4Llee+1UdCQrJVUY1zBsTDcN93V0EeExLiDtQNcOqJXIAgsMBP7/lqZ8lxiYsHTJwSF64+1xCZPXHoWsFET9iHEV3ldKwgf85KyuqJH3b6Ed8YY1L/w1TNInfeKsiHToCBO4Lru10SWvhz6nY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406155; c=relaxed/simple; bh=TThUiSzv0IeiGg3Zm+rPoMl7tKqpff6Xjqe3H1+p5es=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TtVGaVpdVWyANfEj9KND2Z+cqef4uc1UJKV6pG3YaY858hDMRQxDJE/1iLBRY1840DZ+LfDoAyJicsegCPJ8rq1NZQE1gYHSfa7TWslUg3I+WAA4YftEOpgju1Y0V0CYrTlF+re4tV2RXDDWec01l0zBnv35dqHvUnc8KySEWrs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XjDeKl8y; 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="XjDeKl8y" Received: by smtp.kernel.org (Postfix) with ESMTPS id CB7E0C2BCFA; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=TThUiSzv0IeiGg3Zm+rPoMl7tKqpff6Xjqe3H1+p5es=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=XjDeKl8yMLVTIdXAyHBkwlQjVv9zIGksMNFtdT8NaxO4V6eJKlW2fMVjubAU/U8Ka CI2NhegFvkjBQP+Z0Ri2/Dcnw2cp8MBUS7TXxzBueHY72hm/MO9LEyubZQ0djEvYNq UxSdXqML2scEI+ArkErU7e9lPQaYMOa5GM9n802SvyREFca+Ul+etRj8TJ1LwnXR+A co8hZ8CJ/knh+ZEAXssC5eNSuWonfkylg8G4eDLmLMWH6jjrD8NO9ZIjOuY2jkLdFl fVsFof/2zDdNsEFQH5x+tdO3hGZYzbasqv69SuxGwPImO9kxPTZ7RwIaIIsWphHelc mSQf378SVeJbw== 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 B5444C88E6F; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:55 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-14-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=2493; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=m/gjZObWp8hCab6M96EKaw8DHAEZ6xi7L6smiR7GbzY=; b=rnXVgY74a30UHXc+wyXVoP6EU8ZLn0d/jeMbScPXNNuqGMhKenNKy3TiLHdK9+2njQQvoFhc9 nEGmzGkbcZZDqomGRYto19YmQIXqwIwaqH18VCglN9jyhtOIWHTo6tD 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 Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- 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 169832e2a866..b134acfe1542 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4134,8 +4134,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); @@ -4229,9 +4228,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 @@ -4253,8 +4250,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) { @@ -4280,9 +4276,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, @@ -4362,7 +4356,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 09:21:17 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 101FE497B7F for ; Mon, 14 Sep 2026 17:15:55 +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=1789406155; cv=none; b=QfNnBP7zwZN18L1cWzeGJ9gNUol+u2N4iC8eLChoglTcn91Iy1Z1Wnw45jo4BTqD/3IZTi02HOdHqoN/Jt1hkXghcFPIWyycft5ldGOl0CrsZpHP3KIGt36KpeNKH7WPL7OD0ADxPTKGm0MZCUtghrvd4e1g8o8fVxTOTNWV+lA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406155; c=relaxed/simple; bh=PMQHdaDFoVPlbnLKjoEylgmD0i2JbGkUP9Bs0ajFI4A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bxLwSmfr5059AV8uj01C7BVsbmy3VGw3gb+F+YsA7Y1B4mYDwnGYK8KcTbzMFqV7EJ/8uzi4GjuN6B/Y0y+tUJ098A0lxlffHeputNXAOpTmFE/5btWjEWa+OyKCULiRS98iXsXS16wkZc1+ES7k5Q1McWwl/Ba022KRToIdDzQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i5PMS+LQ; 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="i5PMS+LQ" Received: by smtp.kernel.org (Postfix) with ESMTPS id E3D05C2BCF6; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406154; bh=PMQHdaDFoVPlbnLKjoEylgmD0i2JbGkUP9Bs0ajFI4A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=i5PMS+LQdPKMa7GdFCsBTZ+eDdgBjSyGmtc5IuwEKG5bM/XKq4UXTr0CZ3LHC7hbK 2U0rb+HlB0EOZU7XjaM5OaNDWU2ITdreL4YUXux2/smP3NC5xX0W8o4a/3mJFYmbWt lFwzAH/Pn6de5PWBLGjcYC3QTHmpxGa2SCxzLT4xP39YzVs5KH/zz23jzW6t4cAiN2 Wpb24nkyOVyNuythvO07znEO7+wXNaBLbueLNv1MSYV3lRvOJZvsEHkSOetCGPsRHa 9AXOqx7roRWyxNPJ/ZUR/3rYn0++A6lOXEx4nR8089Z8ZHJfmNKjHNfpuh5BGJYNE1 eVnlz+bqO1DEQ== 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 CF5CCC88E72; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:56 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-15-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=2611; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=dr8cj1MiZNdjCIP4W8Q7fhdNiHKYjsEUhKzB6ydXT6A=; b=Xmzz9Kz4mcajOdOHBr/KOP30VBbagZLlKdmPpj1V3hiPN6YbK46VnS2GemrEGwca+qd9ckI8+ cnvl8ltJvEGCPA7vEQYOPW6gb4nkcPgpoNnetICCN89PCjSkaQYR2uW 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() 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 here, so just directly call folio_free_swap() under the lock if it's unmapped, then 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 Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- 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 b134acfe1542..ea8bcace028d 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4327,7 +4327,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; @@ -4367,14 +4368,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: @@ -4401,7 +4404,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 09:21:17 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 22BB1497B93 for ; Mon, 14 Sep 2026 17:15:55 +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=1789406155; cv=none; b=ifLCZGTCFwtKYXqkp/0MPDAc19XAjTfAGMN7kBfYG3VV2u4VGcHgLQUf7zgkcIvbdza74WMKk3r0LfSkRgZI9W1Od99X4pZdH7ZvroRhQTswftLcAGaeaatQnHs5k97sRqsBzVcrk0lK0cly4KD8JET9u4jKLSSyXyZAKg5QEwU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406155; c=relaxed/simple; bh=R3cfJ4kOZ4vv3zzMD2cIpN4aOkeo+1QN/0BkoNF56iQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nGk4BIUK0e1scGSb5lSrm8FN4o36ZB+NUvBc0K2EtO7/WB9VvTvzPplZ5DH4LW+2owjQTGVqWPhvAXXYfBXvn7DaNKeDCx06bm3oSOxXZT+ZVmD3iUwyrYtar1jSfEsqPW6DOQMCEO4cVfcKnavigOiN++6jen+k59UTDL3czVM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MXkpGIf/; 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="MXkpGIf/" Received: by smtp.kernel.org (Postfix) with ESMTPS id 03C31C2BCB8; Mon, 14 Sep 2026 17:15:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406155; bh=R3cfJ4kOZ4vv3zzMD2cIpN4aOkeo+1QN/0BkoNF56iQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=MXkpGIf/asdckGz4DYc0+7f3hqG8QhErtqnNlrv3Ez3yCJ4+ZuDBOUpNC0Yglnagk zolN3whP3Nu5P512pCfYm/ZGElayYaQnL5KcfadWbGvO0aAyt/sxhpiSrBLuNXNX5r V2UkCYvAIAilJxaThvyPFRfGgEyEzTUNqKfMNz9hdkcognCLlKIOkiAl/EYlchkyzU vsk+gNUjhs/0ExNAU3bH5+MrG2bW6lB0F74CVEqDJPXfuMw8eO4Pc4yOczHGXZe9oA zxoc6DrqyIFew1z5pwqgVVTRPSiqcxuzbLJqsSgVglsDUq1U6ZLFvfUSu+pR/rmzCV PHUjKKkgExymA== 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 E4373C88E79; Mon, 14 Sep 2026 17:15:54 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:57 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-16-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=4345; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=LOWEUGV9vnWcliQuTxGteL39iwN2Kn7ndHm2EI5yAVw=; b=ie6374ir/x+K25U6wjmKfoB0/V1PKSM3rsUQuIIKzzyOIKN76JGaAbZhbDmrNN8BDbQ9Moz/Y eHqhH95YDcTCCXWkdYuBHaiBGmnu0Q0G6fglWUZgCQqcJevhOw0Borh 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 Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- 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 ea8bcace028d..fc4dc3f9b563 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3994,10 +3994,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); } @@ -4065,7 +4065,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; } @@ -4102,7 +4102,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) @@ -4110,7 +4110,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); @@ -4139,6 +4139,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; @@ -4209,22 +4210,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 */ @@ -4248,7 +4243,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 @@ -4275,7 +4270,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 09:21:17 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 94BFA499F08 for ; Mon, 14 Sep 2026 17:15:55 +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=1789406155; cv=none; b=T+OZGoEY5/Zge5WkJy8NDVR59Wpwzstl+R16UP2qzvx4ZykZBXtzp3Y1mM07fsBqvSVhPqQjBwmfDDP+RIWLGKcuZBQQsx/nKwuNtVBy3P40fbXG4mYV1st3b1QlHu8927CLf6ukbZqybeqmnTroAwJuAWacF9ND58VscqqPM/4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789406155; c=relaxed/simple; bh=v6q5S1NDfNMBL4jkxSd42kQLlbsw/fbWn+/VmCawMY8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PnRXqnqK8JqOqjXyVLZD1PiDGDHsQDzQCalz7wUy4i/Tkr9G00IGO/5famzM++6nRfMJm1eSlKL3ea6j3qjm7cNYbyFbS4+euHADgH6kfpsHDAqQPQ3RxS5L6CleJ0W3HJo/EP4MDqDKzJuxnVkvPDRW9Jdo3rbhwi8FfwxG/SU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hsA44xQ7; 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="hsA44xQ7" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3A564C2BCF6; Mon, 14 Sep 2026 17:15:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789406155; bh=v6q5S1NDfNMBL4jkxSd42kQLlbsw/fbWn+/VmCawMY8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=hsA44xQ7wNk5+K3d1oMlI6S62Qub6gTZ7W9I6rrn1wBow2dYD2YE2USRG1W4DegOd 64YrM9Xn/vzZNC43vNYHc+Wfh2BmKKGcrEVh+ZLsM/t7gHjqwMy+qSmw8VV+HY09IV dkgHkmmxGYbyyVIyRUBeffCBNY2H4Kw+V3ggSWi9KydYtKpLlf6gwcVLI/jHyZOIyJ vTfcmcaHWlkM7WHFth6tRDcc1b67sDNHr8uidB3iOGZAR4lDGqJ6r+cMcJq6i0bbhc AenWFcdkn0XsTBq6etjG5fK97/zzJxEqsjhq6wH4FNS2jHEa57rcw74CfOc/G6Semg DpZoPS1JkNsNQ== 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 036D7C88E73; Mon, 14 Sep 2026 17:15:55 +0000 (UTC) From: Kairui Song via B4 Relay Date: Tue, 15 Sep 2026 01:14:58 +0800 Subject: [PATCH v5 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: <20260915-swap-thp-cleanup-v5-17-39878b37dfb0@tencent.com> References: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@tencent.com> In-Reply-To: <20260915-swap-thp-cleanup-v5-0-39878b37dfb0@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=1789406149; l=2788; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=+E6N2oy8FpNafU2Z3huhtJo7IvohC2gL0cpJrQRmd9E=; b=Vkn1vtgDfrbSxsGtxl9d7mfIBkJBRGTQUulktuyh7kBaaz+DZJcm4fsJx7vrh7K0SS0EB70ZJ UaRBqz3W1eJBPBnkos8yFgH1tXFyjrFISteDatoWYdmp9bPGOsWhasZ 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 Reviewed-by: Kiryl Shutsemau (Meta) Signed-off-by: Kairui Song --- 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 fc4dc3f9b563..df84a47447c8 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -3830,7 +3830,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) * * @@ -3863,7 +3862,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); @@ -3887,7 +3886,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 @@ -4087,8 +4086,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 @@ -4224,8 +4222,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