From: Usama Arif <usama.arif@linux.dev>
To: "David Hildenbrand (Arm)" <david@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
chrisl@kernel.org, kasong@tencent.com, ljs@kernel.org,
ziy@nvidia.com, linux-mm@kvack.org
Cc: ying.huang@linux.alibaba.com, Baoquan He <baoquan.he@linux.dev>,
willy@infradead.org, youngjun.park@lge.com, hannes@cmpxchg.org,
riel@surriel.com, shakeel.butt@linux.dev, alex@ghiti.fr,
kas@kernel.org, baohua@kernel.org, dev.jain@arm.com,
baolin.wang@linux.alibaba.com, Nico Pache <nico.pache@linux.dev>,
"Liam R. Howlett" <liam@infradead.org>,
ryan.roberts@arm.com, Vlastimil Babka <vbabka@kernel.org>,
lance.yang@linux.dev, linux-kernel@vger.kernel.org,
nphamcs@gmail.com, shikemeng@huaweicloud.com, yosry@kernel.org,
qi.zheng@linux.dev, luizcap@redhat.com, kernel-team@meta.com
Subject: Re: [RESEND v7 10/29] mm: make PMD migration-entry splitting explicit
Date: Tue, 22 Sep 2026 14:15:13 +0100 [thread overview]
Message-ID: <a1cc2eaa-5a36-491d-8ec7-0bcf4132a535@linux.dev> (raw)
In-Reply-To: <35f36d8b-d215-439c-8e77-3a70deed7609@kernel.org>
On 18/09/2026 23:10, David Hildenbrand (Arm) wrote:
> On 9/14/26 14:28, Usama Arif wrote:
>> __split_huge_pmd() and friends take a "freeze" boolean that every caller
>> has to pass and almost every caller passes as false. The name says nothing
>> about what it selects, and the one thing it does select - PTE migration
>> entries instead of PTE mappings - is only ever wanted by the rmap migration
>> path.
>>
>> Rename it to use_migration_entries, keep it private to mm/huge_memory.c,
>> and add split_pmd_to_migration_entries() for try_to_migrate_one(), the only
>> caller that wants it.
>>
>> migrate_vma_split_unmapped_folio() also passed freeze=true, but only ever
>> runs on a PMD that is already a migration entry, which the generic helper
>> expands into PTE migration entries either way. Its folio_get() only existed
>> to balance the put_page() that freeze=true performs, so both go.
>>
>> No functional change intended.
>>
>> Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
>> Signed-off-by: Usama Arif <usama.arif@linux.dev>
>
> [...]
>
>> +void split_pmd_to_migration_entries(struct vm_area_struct *vma,
>> + unsigned long address, pmd_t *pmd);
>
> Two tele tabbies please.
Ack, in next revision.
>
>> bool unmap_huge_pmd_locked(struct vm_area_struct *vma, unsigned long addr,
>> pmd_t *pmdp, struct folio *folio);
>> void map_anon_folio_pmd_nopf(struct folio *folio, pmd_t *pmd,
>> @@ -690,12 +690,14 @@ static inline void deferred_split_folio(struct folio *folio, bool partially_mapp
>> do { } while (0)
>>
>> static inline void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
>> - unsigned long address, bool freeze) {}
>> + unsigned long address) {}
>> static inline void split_huge_pmd_address(struct vm_area_struct *vma,
>> - unsigned long address, bool freeze) {}
>> + unsigned long address) {}
>> static inline void split_huge_pmd_locked(struct vm_area_struct *vma,
>> - unsigned long address, pmd_t *pmd,
>> - bool freeze) {}
>> + unsigned long address, pmd_t *pmd) {}
>> +static inline void
>> +split_pmd_to_migration_entries(struct vm_area_struct *vma,
>> + unsigned long address, pmd_t *pmd) {}
>
> Dito.
>
Ack, in next revision.
>>
>> static inline bool unmap_huge_pmd_locked(struct vm_area_struct *vma,
>> unsigned long addr, pmd_t *pmdp,
>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
>> index ee8d46827ffdc..873887aed0bc2 100644
>> --- a/mm/huge_memory.c
>> +++ b/mm/huge_memory.c
>> @@ -2033,7 +2033,7 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
>> pte_free(dst_mm, pgtable);
>> spin_unlock(src_ptl);
>> spin_unlock(dst_ptl);
>> - __split_huge_pmd(src_vma, src_pmd, addr, false);
>> + __split_huge_pmd(src_vma, src_pmd, addr);
>> return -EAGAIN;
>> }
>> add_mm_counter(dst_mm, MM_ANONPAGES, HPAGE_PMD_NR);
>> @@ -2257,7 +2257,7 @@ vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf)
>> folio_unlock(folio);
>> spin_unlock(vmf->ptl);
>> fallback:
>> - __split_huge_pmd(vma, vmf->pmd, vmf->address, false);
>> + __split_huge_pmd(vma, vmf->pmd, vmf->address);
>> return VM_FAULT_FALLBACK;
>> }
>>
>> @@ -3190,7 +3190,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
>> }
>>
>> static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
>> - unsigned long haddr, bool freeze)
>> + unsigned long haddr, bool use_migration_entries)
>
>
> Just curious: s/use_migration_entries/to_migration_entries/
>
Done for next revision.>> {
>> struct mm_struct *mm = vma->vm_mm;
>> struct folio *folio;
>> @@ -3291,10 +3291,10 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
>> * folios w.r.t anon exclusive handling. See the comments for
>> * folio handling and anon_exclusive below.
>> */
>> - if (freeze && anon_exclusive &&
>> + if (use_migration_entries && anon_exclusive &&
>> folio_try_share_anon_rmap_pmd(folio, page))
>> - freeze = false;
>> - if (!freeze) {
>> + use_migration_entries = false;
>> + if (!use_migration_entries) {
>> rmap_t rmap_flags = RMAP_NONE;
>>
>> folio_ref_add(folio, HPAGE_PMD_NR - 1);
>> @@ -3344,11 +3344,11 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
>> VM_WARN_ON_FOLIO(!folio_test_anon(folio), folio);
>>
>> /*
>> - * Without "freeze", we'll simply split the PMD, propagating the
>> - * PageAnonExclusive() flag for each PTE by setting it for
>> + * Without migration entries, we'll simply split the PMD and
>
> "When not splitting to migration entries .."
>
Ack, in next revision.
>> + * propagate the PageAnonExclusive() flag for each PTE by setting it for
>> * each subpage -- no need to (temporarily) clear.
>
> While at it: s/subpage/page/
Ack, in next revision.
>
>> *
>> - * With "freeze" we want to replace mapped pages by
>> + * With migration entries we want to replace mapped pages by
>
> "When splitting to migration entries ..."
Ack, in next revision.
>
>> * migration entries right away. This is only possible if we
>> * managed to clear PageAnonExclusive() -- see
>> * set_pmd_migration_entry().
>> @@ -3359,10 +3359,10 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
>> * See folio_try_share_anon_rmap_pmd(): invalidate PMD first.
>> */
>> anon_exclusive = PageAnonExclusive(page);
>> - if (freeze && anon_exclusive &&
>> + if (use_migration_entries && anon_exclusive &&
>> folio_try_share_anon_rmap_pmd(folio, page))
>> - freeze = false;
>> - if (!freeze) {
>> + use_migration_entries = false;
>> + if (!use_migration_entries) {
>> rmap_t rmap_flags = RMAP_NONE;
>>
>
> [...]
>
>>
>> smp_wmb(); /* make pte visible before pmd */
>> @@ -3477,15 +3477,28 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
>> }
>>
>> void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
>> - pmd_t *pmd, bool freeze)
>> + pmd_t *pmd)
>
> While at it ...
>
>> {
>> VM_WARN_ON_ONCE(!IS_ALIGNED(address, HPAGE_PMD_SIZE));
>> if (pmd_trans_huge(*pmd) || pmd_is_valid_softleaf(*pmd))
>> - __split_huge_pmd_locked(vma, pmd, address, freeze);
>> + __split_huge_pmd_locked(vma, pmd, address, false);
>> +}
>> +
>> +/*
>> + * Split a present PMD into PTE migration entries, for the rmap migration
>> + * walker. Like split_huge_pmd_locked(), the caller must hold the PMD lock and
>> + * must already be inside an mmu_notifier invalidate range.
>> + */
>
> I'd prefer kerneldoc but I'll let you decide.
Switched to kerneldoc.
>
>> +void split_pmd_to_migration_entries(struct vm_area_struct *vma,
>> + unsigned long address, pmd_t *pmd)
>
> two tabs ...
>
> [...]
>
>> --- a/mm/migrate_device.c
>> +++ b/mm/migrate_device.c
>> @@ -918,12 +918,7 @@ static int migrate_vma_split_unmapped_folio(struct migrate_vma *migrate,
>> unsigned long flags;
>> int ret = 0;
>>
>> - /*
>> - * take a reference, since split_huge_pmd_address() with freeze = true
>> - * drops a reference at the end.
>> - */
>> - folio_get(folio);
>> - split_huge_pmd_address(migrate->vma, addr, true);
>> + split_huge_pmd_address(migrate->vma, addr);
>
>
> Everything up to this point was trivial :)
>
> You say that it already is unmapped (which makes sense looking at the
> function name).
>
> In VM_WARN_ON_ONCE_FOLIO(folio_mapped(folio), folio) we verify.
>
> Did you run the hmm selftests with DEBUG_VM enabled, just to be sure? I remember
> they exercise at least some of the THP logic in here.
>
I have now, with CONFIG_DEBUG_VM=y, CONFIG_DEBUG_VM_PGTABLE=y and
panic_on_warn=1, on this series and on the base commit. The result is
identical either way:
# Totals: pass:35 fail:3 xfail:0 xpass:0 skip:40 error:0
The three failures are file_read, file_write and migrate_file_private,
all of which fail at
hmm-tests.c:828:file_read:Expected fd (-1) >= 0 (0)
i.e. hmm_create_file()'s open("/tmp", O_TMPFILE), which the VM I am using
with 9p /tmp does not support. they fail the same way on the unpatched
kernel. The 40 skips are the DEVICE_COHERENT half.
The 40 skips are the DEVICE_COHERENT half.
>
>> ret = folio_split_unmapped(folio, 0);
>> if (ret)
>> return ret;
>> diff --git a/mm/mprotect.c b/mm/mprotect.c
>> index 2888ee638d872..ee33bbb421008 100644
>> --- a/mm/mprotect.c
>> +++ b/mm/mprotect.c
>> @@ -530,7 +530,7 @@ static inline long change_pmd_range(struct mmu_gather *tlb,
>> if (pmd_is_huge(_pmd)) {
>> if ((next - addr != HPAGE_PMD_SIZE) ||
>> pgtable_split_needed(vma, cp_flags)) {
>> - __split_huge_pmd(vma, pmd, addr, false);
>> + __split_huge_pmd(vma, pmd, addr);
>> /*
>> * For file-backed, the pmd could have been
>> * cleared; make sure pmd populated if
>> diff --git a/mm/rmap.c b/mm/rmap.c
>> index 5332c52909be1..feb751e29b992 100644
>> --- a/mm/rmap.c
>> +++ b/mm/rmap.c
>> @@ -2290,7 +2290,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
>> * restart so we can process the PTE-mapped THP.
>> */
>> split_huge_pmd_locked(vma, pvmw.address,
>> - pvmw.pmd, false);
>> + pvmw.pmd);
>
> You can feel brave and squeeze it into a single line now :)
>
Ack lol>
> Overall LGTM.
>
Thanks for the reviews!!
next prev parent reply other threads:[~2026-09-22 13:15 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-14 12:27 [RESEND v7 00/29] mm: PMD-level swap entries for anonymous THPs Usama Arif
2026-09-14 12:27 ` [RESEND v7 01/29] mm: rename pmd_to_softleaf_folio() to pmd_softleaf_to_folio() Usama Arif
2026-09-14 21:17 ` Barry Song
2026-09-15 3:06 ` Baoquan He
2026-09-15 3:34 ` Qi Zheng
2026-09-14 12:27 ` [RESEND v7 02/29] arm64: mm: add PMD swap-exclusive helpers Usama Arif
2026-09-18 21:11 ` David Hildenbrand (Arm)
2026-09-22 12:34 ` Usama Arif
2026-09-22 14:45 ` David Hildenbrand (Arm)
2026-09-22 15:03 ` Usama Arif
2026-09-14 12:27 ` [RESEND v7 03/29] loongarch: " Usama Arif
2026-09-18 21:18 ` David Hildenbrand (Arm)
2026-09-14 12:27 ` [RESEND v7 04/29] powerpc: " Usama Arif
2026-09-18 21:22 ` David Hildenbrand (Arm)
2026-09-22 12:48 ` Usama Arif
2026-09-14 12:27 ` [RESEND v7 05/29] riscv: " Usama Arif
2026-09-18 21:24 ` David Hildenbrand (Arm)
2026-09-14 12:27 ` [RESEND v7 06/29] s390: " Usama Arif
2026-09-18 21:41 ` David Hildenbrand (Arm)
2026-09-22 12:51 ` Usama Arif
2026-09-14 12:27 ` [RESEND v7 07/29] x86: " Usama Arif
2026-09-16 14:31 ` Kiryl Shutsemau
2026-09-22 12:52 ` Usama Arif
2026-09-18 21:43 ` David Hildenbrand (Arm)
2026-09-22 12:54 ` Usama Arif
2026-09-14 12:27 ` [RESEND v7 08/29] mm: recognize PMD swap entries in the softleaf layer Usama Arif
2026-09-16 14:47 ` Kiryl Shutsemau
2026-09-18 21:56 ` David Hildenbrand (Arm)
2026-09-22 13:08 ` Usama Arif
2026-09-22 14:48 ` David Hildenbrand (Arm)
2026-09-14 12:27 ` [RESEND v7 09/29] mm/debug_vm_pgtable: test PMD swap-exclusive helpers Usama Arif
2026-09-16 14:52 ` Kiryl Shutsemau
2026-09-18 21:57 ` David Hildenbrand (Arm)
2026-09-14 12:28 ` [RESEND v7 10/29] mm: make PMD migration-entry splitting explicit Usama Arif
2026-09-16 14:58 ` Kiryl Shutsemau
2026-09-18 22:10 ` David Hildenbrand (Arm)
2026-09-22 13:15 ` Usama Arif [this message]
2026-09-23 11:04 ` David Hildenbrand (Arm)
2026-09-24 16:12 ` Usama Arif
2026-09-14 12:28 ` [RESEND v7 11/29] mm: split PMD swap entries into PTE swap entries Usama Arif
2026-09-16 15:08 ` Kiryl Shutsemau
2026-09-22 11:46 ` David Hildenbrand (Arm)
2026-09-22 13:18 ` Usama Arif
2026-09-23 11:20 ` David Hildenbrand (Arm)
2026-09-24 17:34 ` Usama Arif
2026-09-24 19:57 ` David Hildenbrand (Arm)
2026-09-14 12:28 ` [RESEND v7 12/29] mm: handle PMD swap entries in fork path Usama Arif
2026-09-24 20:28 ` David Hildenbrand (Arm)
2026-09-25 11:16 ` Usama Arif
2026-09-14 12:28 ` [RESEND v7 13/29] mm: zswap: reject high-order swap cache allocations backed by zswap Usama Arif
2026-09-24 20:30 ` David Hildenbrand (Arm)
2026-09-14 12:28 ` [RESEND v7 14/29] mm: swap in PMD swap entries as whole THPs during swapoff Usama Arif
2026-09-14 12:28 ` [RESEND v7 15/29] fs/proc: account PMD swap entries in smaps Usama Arif
2026-09-24 20:37 ` David Hildenbrand (Arm)
2026-09-25 13:28 ` Usama Arif
2026-09-14 12:28 ` [RESEND v7 16/29] mm: handle soft-dirty and uffd-wp on PMD swap entries Usama Arif
2026-09-14 12:28 ` [RESEND v7 17/29] mm/hmm: fault PMD swap entries on demand Usama Arif
2026-09-14 12:28 ` [RESEND v7 18/29] mm: free PMD swap entries in zap_huge_pmd() Usama Arif
2026-09-14 12:28 ` [RESEND v7 19/29] mm/madvise: free PMD swap entries with MADV_FREE Usama Arif
2026-09-14 12:28 ` [RESEND v7 20/29] mm/madvise: skip PMD swap entries for MADV_COLD and MADV_PAGEOUT Usama Arif
2026-09-14 12:28 ` [RESEND v7 21/29] mm/madvise: keep PMD swap entries whole for MADV_GUARD_INSTALL/REMOVE Usama Arif
2026-09-14 12:28 ` [RESEND v7 22/29] mm/mincore: report PMD swap-cache residency Usama Arif
2026-09-14 12:28 ` [RESEND v7 23/29] mm/khugepaged: treat PMD swap entries as mapped THPs Usama Arif
2026-09-14 12:28 ` [RESEND v7 24/29] mm: handle PMD swap entries in MADV_WILLNEED Usama Arif
2026-09-14 12:28 ` [RESEND v7 25/29] mm: handle PMD swap entries in UFFDIO_MOVE Usama Arif
2026-09-14 12:28 ` [RESEND v7 26/29] mm: don't PTE-batch a swap-in over a hardware-poisoned subpage Usama Arif
2026-09-14 12:28 ` [RESEND v7 27/29] mm: handle PMD swap entry faults on swap-in Usama Arif
2026-09-14 12:28 ` [RESEND v7 28/29] mm: install PMD swap entries on swap-out Usama Arif
2026-09-14 12:28 ` [RESEND v7 29/29] selftests/mm: add PMD swap entry tests Usama Arif
2026-09-15 3:32 ` [RESEND v7 00/29] mm: PMD-level swap entries for anonymous THPs Andrew Morton
2026-09-15 14:09 ` Usama Arif
2026-09-16 0:00 ` Andrew Morton
2026-09-16 10:22 ` Usama Arif
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=a1cc2eaa-5a36-491d-8ec7-0bcf4132a535@linux.dev \
--to=usama.arif@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=baoquan.he@linux.dev \
--cc=chrisl@kernel.org \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=hannes@cmpxchg.org \
--cc=kas@kernel.org \
--cc=kasong@tencent.com \
--cc=kernel-team@meta.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=luizcap@redhat.com \
--cc=nico.pache@linux.dev \
--cc=nphamcs@gmail.com \
--cc=qi.zheng@linux.dev \
--cc=riel@surriel.com \
--cc=ryan.roberts@arm.com \
--cc=shakeel.butt@linux.dev \
--cc=shikemeng@huaweicloud.com \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
--cc=ying.huang@linux.alibaba.com \
--cc=yosry@kernel.org \
--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.