From: "David Hildenbrand (Arm)" <david@kernel.org>
To: kasong@tencent.com, linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
Lorenzo Stoakes <ljs@kernel.org>, Zi Yan <ziy@nvidia.com>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
"Liam R. Howlett" <liam@infradead.org>,
Nico Pache <nico.pache@linux.dev>,
Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
Lance Yang <lance.yang@linux.dev>,
Usama Arif <usama.arif@linux.dev>,
Vlastimil Babka <vbabka@kernel.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>, Chris Li <chrisl@kernel.org>,
Kemeng Shi <shikemeng@huaweicloud.com>,
Nhat Pham <nphamcs@gmail.com>, Baoquan He <baoquan.he@linux.dev>,
Barry Song <baohua@kernel.org>,
Youngjun Park <youngjun.park@lge.com>,
Yeoreum Yun <yeoreum.yun@arm.com>,
"Kiryl Shutsemau (Meta)" <kas@kernel.org>,
Shivam Kalra <shivamkalra98@zohomail.in>,
Kairui Song <ryncsn@gmail.com>
Subject: Re: [PATCH v5 12/17] mm/huge_memory: move anon_vma handling into the anon split helper
Date: Fri, 18 Sep 2026 23:02:22 +0200 [thread overview]
Message-ID: <4015259a-cc44-4bfd-b9c4-39ae96d48057@kernel.org> (raw)
In-Reply-To: <20260915-swap-thp-cleanup-v5-12-39878b37dfb0@tencent.com>
On 9/14/26 19:14, Kairui Song via B4 Relay wrote:
> From: Kairui Song <kasong@tencent.com>
>
> 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() == 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 <ziy@nvidia.com>
> Signed-off-by: Kairui Song <kasong@tencent.com>
> ---
> 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 = NULL;
> int old_order = folio_order(folio);
> struct folio *new_folio, *next;
> + struct anon_vma *anon_vma = NULL;
> enum ttu_flags ttu_flags = 0;
> struct lruvec *lruvec;
> - bool need_remap = false;
> int ret = 0;
>
> + /*
> + * 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.
Helpful, thanks. I'd rewrite the last part to
"Note that entirely swapped-out THPs are unmapped but can be split."
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
next prev parent reply other threads:[~2026-09-18 21:02 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-14 17:14 [PATCH v5 00/17] mm/huge_memory: clean up and decouple the anon and file split helpers Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 01/17] mm/swap: fix off-by-one in swap cache replace sanity check Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 02/17] mm/huge_memory: fix rejection of swap cache folios with a mapping Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 03/17] mm/huge_memory: invert folio_ref_freeze() check to reduce indentation Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 04/17] mm/huge_memory: split the routine for splitting anon and file folio Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 05/17] mm/huge_memory: rename __split_unmapped_folio() to __split_frozen_folio() Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 06/17] mm/huge_memory: consolidate irq and locking for folio split Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 07/17] mm/huge_memory: move EOF trimming into the file split helper Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 08/17] mm/huge_memory: move unmap and remap into the split helpers Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-18 20:48 ` David Hildenbrand (Arm)
2026-09-14 17:14 ` [PATCH v5 09/17] mm/huge_memory: rename remap_page() to remap_anon_folio() Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:28 ` Yeoreum Yun
2026-09-18 20:46 ` David Hildenbrand (Arm)
2026-09-23 12:21 ` Kairui Song
2026-09-14 17:14 ` [PATCH v5 10/17] mm/huge_memory: move the racy refcount check into unmap_folio() Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:29 ` Yeoreum Yun
2026-09-18 20:53 ` David Hildenbrand (Arm)
2026-09-14 17:14 ` [PATCH v5 11/17] mm/huge_memory: move filemap management into the file split helper Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:30 ` Yeoreum Yun
2026-09-18 20:57 ` David Hildenbrand (Arm)
2026-09-14 17:14 ` [PATCH v5 12/17] mm/huge_memory: move anon_vma handling into the anon " Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:27 ` Yeoreum Yun
2026-09-18 21:02 ` David Hildenbrand (Arm) [this message]
2026-09-14 17:14 ` [PATCH v5 13/17] mm/huge_memory: move memcg switch into the file " Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 14/17] mm/huge_memory: drop the unused do_lru argument of " Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-14 17:14 ` [PATCH v5 15/17] mm/huge_memory: clean up after-split folio freeing in __folio_split Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-18 21:03 ` David Hildenbrand (Arm)
2026-09-14 17:14 ` [PATCH v5 16/17] mm/huge_memory: count only swap cache refs in anon folio split Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-18 21:07 ` David Hildenbrand (Arm)
2026-09-14 17:14 ` [PATCH v5 17/17] mm/huge_memory: drop the redundant mapping argument of __split_frozen_folio Kairui Song
2026-09-14 17:14 ` Kairui Song via B4 Relay
2026-09-18 21:04 ` David Hildenbrand (Arm)
2026-09-15 0:45 ` [PATCH v5 00/17] mm/huge_memory: clean up and decouple the anon and file split helpers Andrew Morton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4015259a-cc44-4bfd-b9c4-39ae96d48057@kernel.org \
--to=david@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=baoquan.he@linux.dev \
--cc=chrisl@kernel.org \
--cc=dev.jain@arm.com \
--cc=kas@kernel.org \
--cc=kasong@tencent.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=nico.pache@linux.dev \
--cc=nphamcs@gmail.com \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=ryncsn@gmail.com \
--cc=shikemeng@huaweicloud.com \
--cc=shivamkalra98@zohomail.in \
--cc=surenb@google.com \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=yeoreum.yun@arm.com \
--cc=youngjun.park@lge.com \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.