* [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps
@ 2026-11-09 22:09 Joanne Koong
2026-11-10 11:48 ` David Hildenbrand (Arm)
2026-11-10 22:13 ` sashiko-bot
0 siblings, 2 replies; 7+ messages in thread
From: Joanne Koong @ 2026-11-09 22:09 UTC (permalink / raw)
To: Andrew Morton, David Hildenbrand
Cc: Kiryl Shutsemau, Usama Arif, Barry Song, Lance Yang,
Lorenzo Stoakes, Rik van Riel, Liam R . Howlett, Vlastimil Babka,
Harry Yoo, Jann Horn, Zi Yan, SJ Park, Johannes Weiner, linux-mm,
Sashiko
When try_to_migrate_one() unmaps a large anonymous folio that is mapped by
PTEs, it replaces the PTEs with migration entries one at a time and drops
the rmap for each page with folio_remove_rmap_pte(). After the first PTE
is replaced, __folio_remove_rmap() sees a folio that is no longer fully
mapped but still has pages mapped, and calls
deferred_split_folio(folio, true). That marks the folio
PG_partially_mapped, bumps split_deferred and nr_anon_partially_mapped,
and puts it on the deferred split queue, even though nothing was actually
unmapped. The migration entries are turned back into mappings once the
split or migration is done.
This happens whenever a fully mapped, PTE-mapped anon large folio is
migrated or split. Its effects:
- Migrated folios can later be split for no reason. migrate_folio_move()
copies the source folio's deferred split state to the destination, but
reads it after the unmap, when PG_partially_mapped has already been
wrongly set. So a fully mapped mTHP ends up queued as partially mapped
after migration, and the shrinker can later split it without checking
whether it is underused.
- split_deferred is overcounted. Every such split increments it, so the
stat counts folios that were never partially mapped.
- A folio whose split fails can later be split for no reason. If the
split fails at folio_ref_freeze(), the folio is remapped but stays on
the deferred split queue marked partially mapped. The deferred split
shrinker then splits it without checking whether it is underused,
breaking up a folio that is fully mapped and possibly fully in use.
Mappings replaced by migration entries are not really unmapped, so don't
queue the folio for deferred split when try_to_migrate_one() installs a
migration entry. Pass a flag down to __folio_remove_rmap() and have
try_to_migrate_one() clear it for those PTEs only. PTEs that it replaces
with a hwpoison entry or discards because they are unused are really
unmapped and keep the current behaviour, as do all other callers.
One consequence is that if part of the folio is really unmapped while the
migration entries are in place, zapping the migration entries does not go
through the rmap, so the folio is not marked partially mapped afterwards.
For a split this does not matter, as the folio is split anyway. For a
migrated folio it means the destination is not queued until a later unmap
notices it, which seems preferable to queueing every migrated folio.
Fixes: 8422acdc97ed ("mm: introduce a pageflag for partially mapped folios")
Fixes: a2e0c0668a34 ("mm: migrate: requeue destination folio on deferred split queue")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/sashiko-outbox-198104@kernel.org/
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
---
This bug was found by Sashiko in its review of the mTHP shrinker series
(https://lore.kernel.org/linux-mm/sashiko-outbox-198104@kernel.org/). The
migration / rmap code is still new to me. This patch is a fix with the help of
AI, so I'd appreciate a careful look from people who know this code better.
This was tested in an x86 QEMU guest with 64K mTHP. Splitting 64 fully mapped
folios through the split_huge_pages debugfs file no longer increases
split_deferred (was +64), and migrating 64 to another node no longer leaves
nr_anon_partially_mapped up (was +64). split_huge_page_test, migration, and
khugepaged selftests pass.
mm/rmap.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/mm/rmap.c b/mm/rmap.c
index fa34e1ccbd8f..e5d17481c0c0 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1799,7 +1799,7 @@ void folio_add_file_rmap_pud(struct folio *folio, struct page *page,
static __always_inline void __folio_remove_rmap(struct folio *folio,
struct page *page, int nr_pages, struct vm_area_struct *vma,
- enum pgtable_level level)
+ enum pgtable_level level, bool may_defer_split)
{
atomic_t *mapped = &folio->_nr_pages_mapped;
int last = 0, nr = 0, nr_pmdmapped = 0;
@@ -1888,8 +1888,13 @@ static __always_inline void __folio_remove_rmap(struct folio *folio,
*
* Device private folios do not support deferred splitting and
* shrinker based scanning of the folios to free.
+ *
+ * Skip this if the caller is only replacing the mappings with
+ * migration entries. The folio is not really becoming partially
+ * mapped. Once the split or migration finishes, every migration
+ * entry becomes a mapping again.
*/
- if (partially_mapped && folio_test_anon(folio) &&
+ if (may_defer_split && partially_mapped && folio_test_anon(folio) &&
!folio_test_partially_mapped(folio) &&
!folio_is_device_private(folio))
deferred_split_folio(folio, true);
@@ -1921,7 +1926,7 @@ static __always_inline void __folio_remove_rmap(struct folio *folio,
void folio_remove_rmap_ptes(struct folio *folio, struct page *page,
int nr_pages, struct vm_area_struct *vma)
{
- __folio_remove_rmap(folio, page, nr_pages, vma, PGTABLE_LEVEL_PTE);
+ __folio_remove_rmap(folio, page, nr_pages, vma, PGTABLE_LEVEL_PTE, true);
}
/**
@@ -1938,7 +1943,8 @@ void folio_remove_rmap_pmd(struct folio *folio, struct page *page,
struct vm_area_struct *vma)
{
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
- __folio_remove_rmap(folio, page, HPAGE_PMD_NR, vma, PGTABLE_LEVEL_PMD);
+ __folio_remove_rmap(folio, page, HPAGE_PMD_NR, vma, PGTABLE_LEVEL_PMD,
+ true);
#else
WARN_ON_ONCE(true);
#endif
@@ -1959,7 +1965,8 @@ void folio_remove_rmap_pud(struct folio *folio, struct page *page,
{
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
- __folio_remove_rmap(folio, page, HPAGE_PUD_NR, vma, PGTABLE_LEVEL_PUD);
+ __folio_remove_rmap(folio, page, HPAGE_PUD_NR, vma, PGTABLE_LEVEL_PUD,
+ true);
#else
WARN_ON_ONCE(true);
#endif
@@ -2516,6 +2523,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
mmu_notifier_invalidate_range_start(&range);
while (page_vma_mapped_walk(&pvmw)) {
+ bool may_defer_split = true;
+
/* PMD-mapped THP migration entry */
if (!pvmw.pte) {
__maybe_unused unsigned long pfn;
@@ -2772,12 +2781,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
* No need to invalidate here it will synchronize on
* against the special swap migration pte.
*/
+
+ /*
+ * The folio only looks partially unmapped while this PTE
+ * holds a migration entry, which is later turned back
+ * into a mapping. Don't queue it for deferred split.
+ */
+ may_defer_split = false;
}
if (unlikely(folio_test_hugetlb(folio)))
hugetlb_remove_rmap(folio);
else
- folio_remove_rmap_pte(folio, subpage, vma);
+ __folio_remove_rmap(folio, subpage, 1, vma,
+ PGTABLE_LEVEL_PTE, may_defer_split);
if (vma_test_any_mask(vma, VMA_LOCKED_MASK))
mlock_drain_local();
folio_put(folio);
base-commit: b95f8bb86713c860ce8536d22a988b949b884d5f
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps
2026-11-09 22:09 [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps Joanne Koong
@ 2026-11-10 11:48 ` David Hildenbrand (Arm)
2026-11-10 20:21 ` Joanne Koong
2026-11-10 22:13 ` sashiko-bot
1 sibling, 1 reply; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-10 11:48 UTC (permalink / raw)
To: Joanne Koong, Andrew Morton
Cc: Kiryl Shutsemau, Usama Arif, Barry Song, Lance Yang,
Lorenzo Stoakes, Rik van Riel, Liam R . Howlett, Vlastimil Babka,
Harry Yoo, Jann Horn, Zi Yan, SJ Park, Johannes Weiner, linux-mm,
Sashiko
On 11/9/26 23:09, Joanne Koong wrote:
> When try_to_migrate_one() unmaps a large anonymous folio that is mapped by
> PTEs, it replaces the PTEs with migration entries one at a time and drops
> the rmap for each page with folio_remove_rmap_pte(). After the first PTE
> is replaced, __folio_remove_rmap() sees a folio that is no longer fully
> mapped but still has pages mapped, and calls
> deferred_split_folio(folio, true). That marks the folio
> PG_partially_mapped, bumps split_deferred and nr_anon_partially_mapped,
> and puts it on the deferred split queue, even though nothing was actually
> unmapped. The migration entries are turned back into mappings once the
> split or migration is done.
>
> This happens whenever a fully mapped, PTE-mapped anon large folio is
> migrated or split. Its effects:
>
> - Migrated folios can later be split for no reason. migrate_folio_move()
> copies the source folio's deferred split state to the destination, but
> reads it after the unmap, when PG_partially_mapped has already been
> wrongly set. So a fully mapped mTHP ends up queued as partially mapped
> after migration, and the shrinker can later split it without checking
> whether it is underused.
>
> - split_deferred is overcounted. Every such split increments it, so the
> stat counts folios that were never partially mapped.
>
> - A folio whose split fails can later be split for no reason. If the
> split fails at folio_ref_freeze(), the folio is remapped but stays on
> the deferred split queue marked partially mapped. The deferred split
> shrinker then splits it without checking whether it is underused,
> breaking up a folio that is fully mapped and possibly fully in use.
This is a similar problem I raised in last year's LSF/MM:
https://share.daveh.de/s/bQsDpD7xigJ6wD8/download?path=&files=LSF_MM%2726_+Deferred_folio_splitting.pdf
"
2. THPs erroneously detected as partially-mapped
* Failing migration/split/eviction after stepwise unmap
* Remapping the folio will not fix this up
"
The news here is that we now copy the state to the new folio and can
consequently split the new folio.
>
> Mappings replaced by migration entries are not really unmapped, so don't
> queue the folio for deferred split when try_to_migrate_one() installs a
> migration entry. Pass a flag down to __folio_remove_rmap() and have
> try_to_migrate_one() clear it for those PTEs only. PTEs that it replaces
> with a hwpoison entry or discards because they are unused are really
> unmapped and keep the current behaviour, as do all other callers.
>
> One consequence is that if part of the folio is really unmapped while the
> migration entries are in place, zapping the migration entries does not go
> through the rmap, so the folio is not marked partially mapped afterwards.
> For a split this does not matter, as the folio is split anyway. For a
> migrated folio it means the destination is not queued until a later unmap
> notices it, which seems preferable to queueing every migrated folio.
>
> Fixes: 8422acdc97ed ("mm: introduce a pageflag for partially mapped folios")
> Fixes: a2e0c0668a34 ("mm: migrate: requeue destination folio on deferred split queue")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://lore.kernel.org/all/sashiko-outbox-198104@kernel.org/
> Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
> ---
> This bug was found by Sashiko in its review of the mTHP shrinker series
> (https://lore.kernel.org/linux-mm/sashiko-outbox-198104@kernel.org/). The
> migration / rmap code is still new to me. This patch is a fix with the help of
> AI, so I'd appreciate a careful look from people who know this code better.
Don't we have the same problem for try_to_unmap() in some remaining cases?
See below.
>
> This was tested in an x86 QEMU guest with 64K mTHP. Splitting 64 fully mapped
> folios through the split_huge_pages debugfs file no longer increases
> split_deferred (was +64), and migrating 64 to another node no longer leaves
> nr_anon_partially_mapped up (was +64). split_huge_page_test, migration, and
> khugepaged selftests pass.
>
> mm/rmap.c | 29 +++++++++++++++++++++++------
> 1 file changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/mm/rmap.c b/mm/rmap.c
> index fa34e1ccbd8f..e5d17481c0c0 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
> @@ -1799,7 +1799,7 @@ void folio_add_file_rmap_pud(struct folio *folio, struct page *page,
>
> static __always_inline void __folio_remove_rmap(struct folio *folio,
> struct page *page, int nr_pages, struct vm_area_struct *vma,
> - enum pgtable_level level)
> + enum pgtable_level level, bool may_defer_split)
> {
> atomic_t *mapped = &folio->_nr_pages_mapped;
> int last = 0, nr = 0, nr_pmdmapped = 0;
> @@ -1888,8 +1888,13 @@ static __always_inline void __folio_remove_rmap(struct folio *folio,
> *
> * Device private folios do not support deferred splitting and
> * shrinker based scanning of the folios to free.
> + *
> + * Skip this if the caller is only replacing the mappings with
> + * migration entries. The folio is not really becoming partially
> + * mapped. Once the split or migration finishes, every migration
> + * entry becomes a mapping again.
> */
> - if (partially_mapped && folio_test_anon(folio) &&
> + if (may_defer_split && partially_mapped && folio_test_anon(folio) &&
> !folio_test_partially_mapped(folio) &&
> !folio_is_device_private(folio))
> deferred_split_folio(folio, true);
> @@ -1921,7 +1926,7 @@ static __always_inline void __folio_remove_rmap(struct folio *folio,
> void folio_remove_rmap_ptes(struct folio *folio, struct page *page,
> int nr_pages, struct vm_area_struct *vma)
> {
> - __folio_remove_rmap(folio, page, nr_pages, vma, PGTABLE_LEVEL_PTE);
> + __folio_remove_rmap(folio, page, nr_pages, vma, PGTABLE_LEVEL_PTE, true);
> }
>
> /**
> @@ -1938,7 +1943,8 @@ void folio_remove_rmap_pmd(struct folio *folio, struct page *page,
> struct vm_area_struct *vma)
> {
> #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> - __folio_remove_rmap(folio, page, HPAGE_PMD_NR, vma, PGTABLE_LEVEL_PMD);
> + __folio_remove_rmap(folio, page, HPAGE_PMD_NR, vma, PGTABLE_LEVEL_PMD,
> + true);
> #else
> WARN_ON_ONCE(true);
> #endif
> @@ -1959,7 +1965,8 @@ void folio_remove_rmap_pud(struct folio *folio, struct page *page,
> {
> #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
> defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
> - __folio_remove_rmap(folio, page, HPAGE_PUD_NR, vma, PGTABLE_LEVEL_PUD);
> + __folio_remove_rmap(folio, page, HPAGE_PUD_NR, vma, PGTABLE_LEVEL_PUD,
> + true);
> #else
> WARN_ON_ONCE(true);
> #endif
> @@ -2516,6 +2523,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
> mmu_notifier_invalidate_range_start(&range);
>
> while (page_vma_mapped_walk(&pvmw)) {
> + bool may_defer_split = true;
> +
> /* PMD-mapped THP migration entry */
> if (!pvmw.pte) {
> __maybe_unused unsigned long pfn;
> @@ -2772,12 +2781,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
> * No need to invalidate here it will synchronize on
> * against the special swap migration pte.
> */
> +
> + /*
> + * The folio only looks partially unmapped while this PTE
> + * holds a migration entry, which is later turned back
> + * into a mapping. Don't queue it for deferred split.
> + */
> + may_defer_split = false;
> }
>
> if (unlikely(folio_test_hugetlb(folio)))
> hugetlb_remove_rmap(folio);
> else
> - folio_remove_rmap_pte(folio, subpage, vma);
> + __folio_remove_rmap(folio, subpage, 1, vma,
> + PGTABLE_LEVEL_PTE, may_defer_split);
We will not add such magical boolean parameters. I have a patch to just pass the
rmap flags for a different purpose.
But the whole thing is rather ugly ...
You should probably look at
commit 354dffd29575cdf13154e8fb787322354aa9efc4
Author: Barry Song <baohua@kernel.org>
Date: Fri Feb 14 22:30:14 2025 +1300
mm: support batched unmap for lazyfree large folios during reclamation
Currently, the PTEs and rmap of a large folio are removed one at a time.
This is not only slow but also causes the large folio to be unnecessarily
added to deferred_split, which can lead to races between the
deferred_split shrinker callback and memory reclamation. This patch
releases all PTEs and rmap entries in a batch. Currently, it only handles
lazyfree large folios.
Batching resolves the problem in the common case. For the remaining parts, we
should likely just check in the deferred split handler whether actually
partially mapped to then clear the flag if not.
--
Cheers,
David
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps
2026-11-10 11:48 ` David Hildenbrand (Arm)
@ 2026-11-10 20:21 ` Joanne Koong
2026-11-10 20:55 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 7+ messages in thread
From: Joanne Koong @ 2026-11-10 20:21 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Andrew Morton, Kiryl Shutsemau, Usama Arif, Barry Song,
Lance Yang, Lorenzo Stoakes, Rik van Riel, Liam R . Howlett,
Vlastimil Babka, Harry Yoo, Jann Horn, Zi Yan, SJ Park,
Johannes Weiner, linux-mm, Sashiko
On Tue, Nov 10, 2026 at 3:49 AM David Hildenbrand (Arm)
<david@kernel.org> wrote:
>
Hi David,
Thanks for reviewing this.
> > - A folio whose split fails can later be split for no reason. If the
> > split fails at folio_ref_freeze(), the folio is remapped but stays on
> > the deferred split queue marked partially mapped. The deferred split
> > shrinker then splits it without checking whether it is underused,
> > breaking up a folio that is fully mapped and possibly fully in use.
>
> This is a similar problem I raised in last year's LSF/MM:
>
> https://share.daveh.de/s/bQsDpD7xigJ6wD8/download?path=&files=LSF_MM%2726_+Deferred_folio_splitting.pdf
Awesome, I'll make sure to add in a link to this presentation in the
cover letter of v2.
>
> "
> 2. THPs erroneously detected as partially-mapped
> * Failing migration/split/eviction after stepwise unmap
> * Remapping the folio will not fix this up
> "
>
> The news here is that we now copy the state to the new folio and can
> consequently split the new folio.
>
>
> >
> > Mappings replaced by migration entries are not really unmapped, so don't
> > queue the folio for deferred split when try_to_migrate_one() installs a
> > migration entry. Pass a flag down to __folio_remove_rmap() and have
> > try_to_migrate_one() clear it for those PTEs only. PTEs that it replaces
> > with a hwpoison entry or discards because they are unused are really
> > unmapped and keep the current behaviour, as do all other callers.
> >
> > One consequence is that if part of the folio is really unmapped while the
> > migration entries are in place, zapping the migration entries does not go
> > through the rmap, so the folio is not marked partially mapped afterwards.
> > For a split this does not matter, as the folio is split anyway. For a
> > migrated folio it means the destination is not queued until a later unmap
> > notices it, which seems preferable to queueing every migrated folio.
> >
> > Fixes: 8422acdc97ed ("mm: introduce a pageflag for partially mapped folios")
> > Fixes: a2e0c0668a34 ("mm: migrate: requeue destination folio on deferred split queue")
> > Reported-by: Sashiko <sashiko-bot@kernel.org>
> > Closes: https://lore.kernel.org/all/sashiko-outbox-198104@kernel.org/
> > Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
> > ---
> > This bug was found by Sashiko in its review of the mTHP shrinker series
> > (https://lore.kernel.org/linux-mm/sashiko-outbox-198104@kernel.org/). The
> > migration / rmap code is still new to me. This patch is a fix with the help of
> > AI, so I'd appreciate a careful look from people who know this code better.
>
> Don't we have the same problem for try_to_unmap() in some remaining cases?
>
> See below.
>
> >
> > This was tested in an x86 QEMU guest with 64K mTHP. Splitting 64 fully mapped
> > folios through the split_huge_pages debugfs file no longer increases
> > split_deferred (was +64), and migrating 64 to another node no longer leaves
> > nr_anon_partially_mapped up (was +64). split_huge_page_test, migration, and
> > khugepaged selftests pass.
> >
> > mm/rmap.c | 29 +++++++++++++++++++++++------
> > 1 file changed, 23 insertions(+), 6 deletions(-)
> >
> > diff --git a/mm/rmap.c b/mm/rmap.c
> > index fa34e1ccbd8f..e5d17481c0c0 100644
> > --- a/mm/rmap.c
> > +++ b/mm/rmap.c
> > @@ -2772,12 +2781,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
> > + /*
> > + * The folio only looks partially unmapped while this PTE
> > + * holds a migration entry, which is later turned back
> > + * into a mapping. Don't queue it for deferred split.
> > + */
> > + may_defer_split = false;
> > }
> >
> > if (unlikely(folio_test_hugetlb(folio)))
> > hugetlb_remove_rmap(folio);
> > else
> > - folio_remove_rmap_pte(folio, subpage, vma);
> > + __folio_remove_rmap(folio, subpage, 1, vma,
> > + PGTABLE_LEVEL_PTE, may_defer_split);
> We will not add such magical boolean parameters. I have a patch to just pass the
> rmap flags for a different purpose.
>
> But the whole thing is rather ugly ...
>
>
> You should probably look at
>
> commit 354dffd29575cdf13154e8fb787322354aa9efc4
> Author: Barry Song <baohua@kernel.org>
> Date: Fri Feb 14 22:30:14 2025 +1300
>
> mm: support batched unmap for lazyfree large folios during reclamation
>
> Currently, the PTEs and rmap of a large folio are removed one at a time.
> This is not only slow but also causes the large folio to be unnecessarily
> added to deferred_split, which can lead to races between the
> deferred_split shrinker callback and memory reclamation. This patch
> releases all PTEs and rmap entries in a batch. Currently, it only handles
> lazyfree large folios.
>
> Batching resolves the problem in the common case. For the remaining parts, we
> should likely just check in the deferred split handler whether actually
> partially mapped to then clear the flag if not.
This sounds great. I'll look at Barry's commit and rework this patch
to batch the unmap, and I'll add a patch for the check to cover the
edge cases.
Thanks,
Joanne
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps
2026-11-10 20:21 ` Joanne Koong
@ 2026-11-10 20:55 ` David Hildenbrand (Arm)
2026-11-10 21:05 ` Zi Yan
0 siblings, 1 reply; 7+ messages in thread
From: David Hildenbrand (Arm) @ 2026-11-10 20:55 UTC (permalink / raw)
To: Joanne Koong
Cc: Andrew Morton, Kiryl Shutsemau, Usama Arif, Barry Song,
Lance Yang, Lorenzo Stoakes, Rik van Riel, Liam R . Howlett,
Vlastimil Babka, Harry Yoo, Jann Horn, Zi Yan, SJ Park,
Johannes Weiner, linux-mm, Sashiko
On 11/10/26 21:21, Joanne Koong wrote:
> On Tue, Nov 10, 2026 at 3:49 AM David Hildenbrand (Arm)
> <david@kernel.org> wrote:
>>
>
> Hi David,
>
> Thanks for reviewing this.
>
>>> - A folio whose split fails can later be split for no reason. If the
>>> split fails at folio_ref_freeze(), the folio is remapped but stays on
>>> the deferred split queue marked partially mapped. The deferred split
>>> shrinker then splits it without checking whether it is underused,
>>> breaking up a folio that is fully mapped and possibly fully in use.
>>
>> This is a similar problem I raised in last year's LSF/MM:
>>
>> https://share.daveh.de/s/bQsDpD7xigJ6wD8/download?path=&files=LSF_MM%2726_+Deferred_folio_splitting.pdf
>
> Awesome, I'll make sure to add in a link to this presentation in the
> cover letter of v2.
>
>>
>> "
>> 2. THPs erroneously detected as partially-mapped
>> * Failing migration/split/eviction after stepwise unmap
>> * Remapping the folio will not fix this up
>> "
>>
>> The news here is that we now copy the state to the new folio and can
>> consequently split the new folio.
>>
>>
>>>
>>> Mappings replaced by migration entries are not really unmapped, so don't
>>> queue the folio for deferred split when try_to_migrate_one() installs a
>>> migration entry. Pass a flag down to __folio_remove_rmap() and have
>>> try_to_migrate_one() clear it for those PTEs only. PTEs that it replaces
>>> with a hwpoison entry or discards because they are unused are really
>>> unmapped and keep the current behaviour, as do all other callers.
>>>
>>> One consequence is that if part of the folio is really unmapped while the
>>> migration entries are in place, zapping the migration entries does not go
>>> through the rmap, so the folio is not marked partially mapped afterwards.
>>> For a split this does not matter, as the folio is split anyway. For a
>>> migrated folio it means the destination is not queued until a later unmap
>>> notices it, which seems preferable to queueing every migrated folio.
>>>
>>> Fixes: 8422acdc97ed ("mm: introduce a pageflag for partially mapped folios")
>>> Fixes: a2e0c0668a34 ("mm: migrate: requeue destination folio on deferred split queue")
>>> Reported-by: Sashiko <sashiko-bot@kernel.org>
>>> Closes: https://lore.kernel.org/all/sashiko-outbox-198104@kernel.org/
>>> Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
>>> ---
>>> This bug was found by Sashiko in its review of the mTHP shrinker series
>>> (https://lore.kernel.org/linux-mm/sashiko-outbox-198104@kernel.org/). The
>>> migration / rmap code is still new to me. This patch is a fix with the help of
>>> AI, so I'd appreciate a careful look from people who know this code better.
>>
>> Don't we have the same problem for try_to_unmap() in some remaining cases?
>>
>> See below.
>>
>>>
>>> This was tested in an x86 QEMU guest with 64K mTHP. Splitting 64 fully mapped
>>> folios through the split_huge_pages debugfs file no longer increases
>>> split_deferred (was +64), and migrating 64 to another node no longer leaves
>>> nr_anon_partially_mapped up (was +64). split_huge_page_test, migration, and
>>> khugepaged selftests pass.
>>>
>>> mm/rmap.c | 29 +++++++++++++++++++++++------
>>> 1 file changed, 23 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/mm/rmap.c b/mm/rmap.c
>>> index fa34e1ccbd8f..e5d17481c0c0 100644
>>> --- a/mm/rmap.c
>>> +++ b/mm/rmap.c
>>> @@ -2772,12 +2781,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
>>> + /*
>>> + * The folio only looks partially unmapped while this PTE
>>> + * holds a migration entry, which is later turned back
>>> + * into a mapping. Don't queue it for deferred split.
>>> + */
>>> + may_defer_split = false;
>>> }
>>>
>>> if (unlikely(folio_test_hugetlb(folio)))
>>> hugetlb_remove_rmap(folio);
>>> else
>>> - folio_remove_rmap_pte(folio, subpage, vma);
>>> + __folio_remove_rmap(folio, subpage, 1, vma,
>>> + PGTABLE_LEVEL_PTE, may_defer_split);
>> We will not add such magical boolean parameters. I have a patch to just pass the
>> rmap flags for a different purpose.
>>
>> But the whole thing is rather ugly ...
>>
>>
>> You should probably look at
>>
>> commit 354dffd29575cdf13154e8fb787322354aa9efc4
>> Author: Barry Song <baohua@kernel.org>
>> Date: Fri Feb 14 22:30:14 2025 +1300
>>
>> mm: support batched unmap for lazyfree large folios during reclamation
>>
>> Currently, the PTEs and rmap of a large folio are removed one at a time.
>> This is not only slow but also causes the large folio to be unnecessarily
>> added to deferred_split, which can lead to races between the
>> deferred_split shrinker callback and memory reclamation. This patch
>> releases all PTEs and rmap entries in a batch. Currently, it only handles
>> lazyfree large folios.
>>
>> Batching resolves the problem in the common case. For the remaining parts, we
>> should likely just check in the deferred split handler whether actually
>> partially mapped to then clear the flag if not.
>
> This sounds great. I'll look at Barry's commit and rework this patch
> to batch the unmap, and I'll add a patch for the check to cover the
> edge cases.
Take a look on the list, we might have already had some attempts to batch in
there (we just lacked the capacity to review them). But maybe I am daydreaming :)
--
Cheers,
David
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps
2026-11-10 20:55 ` David Hildenbrand (Arm)
@ 2026-11-10 21:05 ` Zi Yan
2026-11-10 23:26 ` Joanne Koong
0 siblings, 1 reply; 7+ messages in thread
From: Zi Yan @ 2026-11-10 21:05 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Joanne Koong, Andrew Morton, Kiryl Shutsemau, Usama Arif,
Barry Song, Lance Yang, Lorenzo Stoakes, Rik van Riel,
Liam R . Howlett, Vlastimil Babka, Harry Yoo, Jann Horn, SJ Park,
Johannes Weiner, linux-mm, Sashiko
On 10 Nov 2026, at 15:55, David Hildenbrand (Arm) wrote:
> On 11/10/26 21:21, Joanne Koong wrote:
>> On Tue, Nov 10, 2026 at 3:49 AM David Hildenbrand (Arm)
>> <david@kernel.org> wrote:
>>>
>>
>> Hi David,
>>
>> Thanks for reviewing this.
>>
>>>> - A folio whose split fails can later be split for no reason. If the
>>>> split fails at folio_ref_freeze(), the folio is remapped but stays on
>>>> the deferred split queue marked partially mapped. The deferred split
>>>> shrinker then splits it without checking whether it is underused,
>>>> breaking up a folio that is fully mapped and possibly fully in use.
>>>
>>> This is a similar problem I raised in last year's LSF/MM:
>>>
>>> https://share.daveh.de/s/bQsDpD7xigJ6wD8/download?path=&files=LSF_MM%2726_+Deferred_folio_splitting.pdf
>>
>> Awesome, I'll make sure to add in a link to this presentation in the
>> cover letter of v2.
>>
>>>
>>> "
>>> 2. THPs erroneously detected as partially-mapped
>>> * Failing migration/split/eviction after stepwise unmap
>>> * Remapping the folio will not fix this up
>>> "
>>>
>>> The news here is that we now copy the state to the new folio and can
>>> consequently split the new folio.
>>>
>>>
>>>>
>>>> Mappings replaced by migration entries are not really unmapped, so don't
>>>> queue the folio for deferred split when try_to_migrate_one() installs a
>>>> migration entry. Pass a flag down to __folio_remove_rmap() and have
>>>> try_to_migrate_one() clear it for those PTEs only. PTEs that it replaces
>>>> with a hwpoison entry or discards because they are unused are really
>>>> unmapped and keep the current behaviour, as do all other callers.
>>>>
>>>> One consequence is that if part of the folio is really unmapped while the
>>>> migration entries are in place, zapping the migration entries does not go
>>>> through the rmap, so the folio is not marked partially mapped afterwards.
>>>> For a split this does not matter, as the folio is split anyway. For a
>>>> migrated folio it means the destination is not queued until a later unmap
>>>> notices it, which seems preferable to queueing every migrated folio.
>>>>
>>>> Fixes: 8422acdc97ed ("mm: introduce a pageflag for partially mapped folios")
>>>> Fixes: a2e0c0668a34 ("mm: migrate: requeue destination folio on deferred split queue")
>>>> Reported-by: Sashiko <sashiko-bot@kernel.org>
>>>> Closes: https://lore.kernel.org/all/sashiko-outbox-198104@kernel.org/
>>>> Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
>>>> ---
>>>> This bug was found by Sashiko in its review of the mTHP shrinker series
>>>> (https://lore.kernel.org/linux-mm/sashiko-outbox-198104@kernel.org/). The
>>>> migration / rmap code is still new to me. This patch is a fix with the help of
>>>> AI, so I'd appreciate a careful look from people who know this code better.
>>>
>>> Don't we have the same problem for try_to_unmap() in some remaining cases?
>>>
>>> See below.
>>>
>>>>
>>>> This was tested in an x86 QEMU guest with 64K mTHP. Splitting 64 fully mapped
>>>> folios through the split_huge_pages debugfs file no longer increases
>>>> split_deferred (was +64), and migrating 64 to another node no longer leaves
>>>> nr_anon_partially_mapped up (was +64). split_huge_page_test, migration, and
>>>> khugepaged selftests pass.
>>>>
>>>> mm/rmap.c | 29 +++++++++++++++++++++++------
>>>> 1 file changed, 23 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/mm/rmap.c b/mm/rmap.c
>>>> index fa34e1ccbd8f..e5d17481c0c0 100644
>>>> --- a/mm/rmap.c
>>>> +++ b/mm/rmap.c
>>>> @@ -2772,12 +2781,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
>>>> + /*
>>>> + * The folio only looks partially unmapped while this PTE
>>>> + * holds a migration entry, which is later turned back
>>>> + * into a mapping. Don't queue it for deferred split.
>>>> + */
>>>> + may_defer_split = false;
>>>> }
>>>>
>>>> if (unlikely(folio_test_hugetlb(folio)))
>>>> hugetlb_remove_rmap(folio);
>>>> else
>>>> - folio_remove_rmap_pte(folio, subpage, vma);
>>>> + __folio_remove_rmap(folio, subpage, 1, vma,
>>>> + PGTABLE_LEVEL_PTE, may_defer_split);
>>> We will not add such magical boolean parameters. I have a patch to just pass the
>>> rmap flags for a different purpose.
>>>
>>> But the whole thing is rather ugly ...
>>>
>>>
>>> You should probably look at
>>>
>>> commit 354dffd29575cdf13154e8fb787322354aa9efc4
>>> Author: Barry Song <baohua@kernel.org>
>>> Date: Fri Feb 14 22:30:14 2025 +1300
>>>
>>> mm: support batched unmap for lazyfree large folios during reclamation
>>>
>>> Currently, the PTEs and rmap of a large folio are removed one at a time.
>>> This is not only slow but also causes the large folio to be unnecessarily
>>> added to deferred_split, which can lead to races between the
>>> deferred_split shrinker callback and memory reclamation. This patch
>>> releases all PTEs and rmap entries in a batch. Currently, it only handles
>>> lazyfree large folios.
>>>
>>> Batching resolves the problem in the common case. For the remaining parts, we
>>> should likely just check in the deferred split handler whether actually
>>> partially mapped to then clear the flag if not.
>>
>> This sounds great. I'll look at Barry's commit and rework this patch
>> to batch the unmap, and I'll add a patch for the check to cover the
>> edge cases.
>
> Take a look on the list, we might have already had some attempts to batch in
> there (we just lacked the capacity to review them). But maybe I am daydreaming :)
You mean the last patch from Shivank[1].
[1] https://lore.kernel.org/all/20260813-migrate-rmap-batch-v2-7-3c5424c555c7@amd.com/
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps
2026-11-10 21:05 ` Zi Yan
@ 2026-11-10 23:26 ` Joanne Koong
0 siblings, 0 replies; 7+ messages in thread
From: Joanne Koong @ 2026-11-10 23:26 UTC (permalink / raw)
To: Zi Yan
Cc: David Hildenbrand (Arm), Andrew Morton, Kiryl Shutsemau,
Usama Arif, Barry Song, Lance Yang, Lorenzo Stoakes, Rik van Riel,
Liam R . Howlett, Vlastimil Babka, Harry Yoo, Jann Horn, SJ Park,
Johannes Weiner, linux-mm, Sashiko
On Tue, Nov 10, 2026 at 1:05 PM Zi Yan <ziy@nvidia.com> wrote:
>
> On 10 Nov 2026, at 15:55, David Hildenbrand (Arm) wrote:
>
> > On 11/10/26 21:21, Joanne Koong wrote:
> >> On Tue, Nov 10, 2026 at 3:49 AM David Hildenbrand (Arm)
> >> <david@kernel.org> wrote:
> >>>
> >>
> >> Hi David,
> >>
> >> Thanks for reviewing this.
> >>
> >>>> - A folio whose split fails can later be split for no reason. If the
> >>>> split fails at folio_ref_freeze(), the folio is remapped but stays on
> >>>> the deferred split queue marked partially mapped. The deferred split
> >>>> shrinker then splits it without checking whether it is underused,
> >>>> breaking up a folio that is fully mapped and possibly fully in use.
> >>>
> >>> This is a similar problem I raised in last year's LSF/MM:
> >>>
> >>> https://share.daveh.de/s/bQsDpD7xigJ6wD8/download?path=&files=LSF_MM%2726_+Deferred_folio_splitting.pdf
> >>
> >> Awesome, I'll make sure to add in a link to this presentation in the
> >> cover letter of v2.
> >>
> >>>
> >>> "
> >>> 2. THPs erroneously detected as partially-mapped
> >>> * Failing migration/split/eviction after stepwise unmap
> >>> * Remapping the folio will not fix this up
> >>> "
> >>>
> >>> The news here is that we now copy the state to the new folio and can
> >>> consequently split the new folio.
> >>>
> >>>
> >>>>
> >>>> Mappings replaced by migration entries are not really unmapped, so don't
> >>>> queue the folio for deferred split when try_to_migrate_one() installs a
> >>>> migration entry. Pass a flag down to __folio_remove_rmap() and have
> >>>> try_to_migrate_one() clear it for those PTEs only. PTEs that it replaces
> >>>> with a hwpoison entry or discards because they are unused are really
> >>>> unmapped and keep the current behaviour, as do all other callers.
> >>>>
> >>>> One consequence is that if part of the folio is really unmapped while the
> >>>> migration entries are in place, zapping the migration entries does not go
> >>>> through the rmap, so the folio is not marked partially mapped afterwards.
> >>>> For a split this does not matter, as the folio is split anyway. For a
> >>>> migrated folio it means the destination is not queued until a later unmap
> >>>> notices it, which seems preferable to queueing every migrated folio.
> >>>>
> >>>> Fixes: 8422acdc97ed ("mm: introduce a pageflag for partially mapped folios")
> >>>> Fixes: a2e0c0668a34 ("mm: migrate: requeue destination folio on deferred split queue")
> >>>> Reported-by: Sashiko <sashiko-bot@kernel.org>
> >>>> Closes: https://lore.kernel.org/all/sashiko-outbox-198104@kernel.org/
> >>>> Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
> >>>> ---
> >>>> This bug was found by Sashiko in its review of the mTHP shrinker series
> >>>> (https://lore.kernel.org/linux-mm/sashiko-outbox-198104@kernel.org/). The
> >>>> migration / rmap code is still new to me. This patch is a fix with the help of
> >>>> AI, so I'd appreciate a careful look from people who know this code better.
> >>>
> >>> Don't we have the same problem for try_to_unmap() in some remaining cases?
> >>>
> >>> See below.
> >>>
> >>>>
> >>>> This was tested in an x86 QEMU guest with 64K mTHP. Splitting 64 fully mapped
> >>>> folios through the split_huge_pages debugfs file no longer increases
> >>>> split_deferred (was +64), and migrating 64 to another node no longer leaves
> >>>> nr_anon_partially_mapped up (was +64). split_huge_page_test, migration, and
> >>>> khugepaged selftests pass.
> >>>>
> >>>> mm/rmap.c | 29 +++++++++++++++++++++++------
> >>>> 1 file changed, 23 insertions(+), 6 deletions(-)
> >>>>
> >>>> diff --git a/mm/rmap.c b/mm/rmap.c
> >>>> index fa34e1ccbd8f..e5d17481c0c0 100644
> >>>> --- a/mm/rmap.c
> >>>> +++ b/mm/rmap.c
> >>>> @@ -2772,12 +2781,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
> >>>> + /*
> >>>> + * The folio only looks partially unmapped while this PTE
> >>>> + * holds a migration entry, which is later turned back
> >>>> + * into a mapping. Don't queue it for deferred split.
> >>>> + */
> >>>> + may_defer_split = false;
> >>>> }
> >>>>
> >>>> if (unlikely(folio_test_hugetlb(folio)))
> >>>> hugetlb_remove_rmap(folio);
> >>>> else
> >>>> - folio_remove_rmap_pte(folio, subpage, vma);
> >>>> + __folio_remove_rmap(folio, subpage, 1, vma,
> >>>> + PGTABLE_LEVEL_PTE, may_defer_split);
> >>> We will not add such magical boolean parameters. I have a patch to just pass the
> >>> rmap flags for a different purpose.
> >>>
> >>> But the whole thing is rather ugly ...
> >>>
> >>>
> >>> You should probably look at
> >>>
> >>> commit 354dffd29575cdf13154e8fb787322354aa9efc4
> >>> Author: Barry Song <baohua@kernel.org>
> >>> Date: Fri Feb 14 22:30:14 2025 +1300
> >>>
> >>> mm: support batched unmap for lazyfree large folios during reclamation
> >>>
> >>> Currently, the PTEs and rmap of a large folio are removed one at a time.
> >>> This is not only slow but also causes the large folio to be unnecessarily
> >>> added to deferred_split, which can lead to races between the
> >>> deferred_split shrinker callback and memory reclamation. This patch
> >>> releases all PTEs and rmap entries in a batch. Currently, it only handles
> >>> lazyfree large folios.
> >>>
> >>> Batching resolves the problem in the common case. For the remaining parts, we
> >>> should likely just check in the deferred split handler whether actually
> >>> partially mapped to then clear the flag if not.
> >>
> >> This sounds great. I'll look at Barry's commit and rework this patch
> >> to batch the unmap, and I'll add a patch for the check to cover the
> >> edge cases.
> >
> > Take a look on the list, we might have already had some attempts to batch in
> > there (we just lacked the capacity to review them). But maybe I am daydreaming :)
>
> You mean the last patch from Shivank[1].
>
> [1] https://lore.kernel.org/all/20260813-migrate-rmap-batch-v2-7-3c5424c555c7@amd.com/
Thanks for the link, Zi! I'll follow up on Shivank's series to ask
whether there's a v3 planned. In the meantime, I'll work on the
deferred_split_scan() check.
Thanks,
Joanne
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps
2026-11-09 22:09 [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps Joanne Koong
2026-11-10 11:48 ` David Hildenbrand (Arm)
@ 2026-11-10 22:13 ` sashiko-bot
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-11-10 22:13 UTC (permalink / raw)
To: Joanne Koong, Andrew Morton, David Hildenbrand
Cc: Kiryl Shutsemau, Usama Arif, Barry Song, Lance Yang,
Lorenzo Stoakes, Rik van Riel, Liam R . Howlett, Vlastimil Babka,
Harry Yoo, Jann Horn, Zi Yan, SJ Park, Johannes Weiner, linux-mm
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] mm/rmap: PMD migration entries still queue folios for
deferred split
- [Low] mm/rmap: try_to_migrate_one() misses deferred split on last PTE
unmap
--
commit 685cbbfa9eaed572b053e5452f3d93b8fec2771b
Author: Joanne Koong <joannelkoong@gmail.com>
mm/rmap: fix migration entries being treated as partial unmaps
This commit adds a may_defer_split parameter to __folio_remove_rmap() and
passes false from try_to_migrate_one() when installing PTE migration
entries, preventing temporary migration entries from queueing anonymous
large folios for deferred splitting.
> diff --git a/mm/rmap.c b/mm/rmap.c
> index fa34e1ccbd8f2..e5d17481c0c01 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
[ ... ]
> @@ -1938,7 +1943,8 @@ void folio_remove_rmap_pmd(struct folio *folio, struct page *page,
> struct vm_area_struct *vma)
> {
> #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> - __folio_remove_rmap(folio, page, HPAGE_PMD_NR, vma, PGTABLE_LEVEL_PMD);
> + __folio_remove_rmap(folio, page, HPAGE_PMD_NR, vma, PGTABLE_LEVEL_PMD,
> + true);
> #else
> WARN_ON_ONCE(true);
> #endif
[Severity: Medium]
Can replacing a PMD mapping with migration entries still queue a fully
mapped folio for deferred split?
When try_to_migrate_one() replaces a PMD via set_pmd_migration_entry() or
split_huge_pmd_locked(..., true) -> __split_huge_pmd_locked(), both paths
call folio_remove_rmap_pmd(), which unconditionally passes
may_defer_split = true to __folio_remove_rmap().
If the folio is PMD-mapped in a parent process after fork() and the child
has unmapped or CoW-faulted one subpage so its VMA holds 511 PTE mappings,
removing the parent's PMD rmap sees 0 < nr < nr_pmdmapped (or
last && nr < folio_large_nr_pages(folio) under CONFIG_NO_PAGE_MAPCOUNT)
and calls deferred_split_folio(folio, true). migrate_folio_move() then
propagates PG_partially_mapped to the destination folio, causing the
shrinker to split the migrated THP even though all 512 pages remain mapped
in the parent.
[ ... ]
> @@ -2516,6 +2523,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
> mmu_notifier_invalidate_range_start(&range);
>
> while (page_vma_mapped_walk(&pvmw)) {
> + bool may_defer_split = true;
> +
> /* PMD-mapped THP migration entry */
> if (!pvmw.pte) {
> __maybe_unused unsigned long pfn;
> @@ -2772,12 +2781,20 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
> * No need to invalidate here it will synchronize on
> * against the special swap migration pte.
> */
> +
> + /*
> + * The folio only looks partially unmapped while this PTE
> + * holds a migration entry, which is later turned back
> + * into a mapping. Don't queue it for deferred split.
> + */
> + may_defer_split = false;
> }
>
> if (unlikely(folio_test_hugetlb(folio)))
> hugetlb_remove_rmap(folio);
> else
> - folio_remove_rmap_pte(folio, subpage, vma);
> + __folio_remove_rmap(folio, subpage, 1, vma,
> + PGTABLE_LEVEL_PTE, may_defer_split);
[Severity: Low]
Does try_to_migrate_one() miss queueing the folio for deferred split when
the last mapped PTE is unmapped via PageHWPoison(subpage) or
pte_unused(pteval)?
Each earlier PTE converted to a migration entry calls
__folio_remove_rmap() with may_defer_split = false, which still decrements
_nr_pages_mapped (and _large_mapcount). When the final mapped PTE is
genuinely unmapped with may_defer_split = true, _nr_pages_mapped (or
_large_mapcount under CONFIG_NO_PAGE_MAPCOUNT) drops from 1 to 0, so
__folio_remove_rmap() sees the folio as completely unmapped and sets
partially_mapped = false. Once remove_migration_ptes() restores the
earlier migration entries, the folio is left partially mapped without
PG_partially_mapped set or being queued on deferred_split_lru.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109220958.2071687-1-joannelkoong@gmail.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-10 23:26 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 22:09 [PATCH v1] mm/rmap: fix migration entries being treated as partial unmaps Joanne Koong
2026-11-10 11:48 ` David Hildenbrand (Arm)
2026-11-10 20:21 ` Joanne Koong
2026-11-10 20:55 ` David Hildenbrand (Arm)
2026-11-10 21:05 ` Zi Yan
2026-11-10 23:26 ` Joanne Koong
2026-11-10 22:13 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox