[PATCH v3] mm: migrate: requeue destination folio on deferred split queue

Usama Arif posted 1 patch 3 weeks, 5 days ago
mm/migrate.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
[PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by Usama Arif 3 weeks, 5 days ago
During folio migration, __folio_migrate_mapping() removes the source
folio from the deferred split queue, but the destination folio is never
re-queued.  This causes underutilized THPs to escape the shrinker after
NUMA migration, since they silently drop off the deferred split list.

Fix this by recording whether the source folio was on the deferred split
queue and its partially mapped state before move_to_new_folio() unqueues
it, and re-queuing the destination folio after a successful migration if
it was.

By the time migrate_folio_move() runs, partially mapped folios without a
pin have already been split by migrate_pages_batch().  So only two cases
remain on the deferred list at this point:
  1. Partially mapped folios with a pin (split failed).
  2. Fully mapped but potentially underused folios.
The recorded partially_mapped state is forwarded to deferred_split_folio()
so that the destination folio is correctly re-queued in both cases.

Reported-by: Johannes Weiner <hannes@cmpxchg.org>
Fixes: dafff3f4c850 ("mm: split underused THPs")
Acked-by: Zi Yan <ziy@nvidia.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Usama Arif <usama.arif@linux.dev>
---
v2 -> v3:
- Remove redundant folio_test_large_rmappable() check (David).
- Check order > 1 (replaced folio_test_large()) (Wei Yang)
---
 mm/migrate.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/mm/migrate.c b/mm/migrate.c
index ece77ccb2ec0..f5169a9f8f24 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1360,6 +1360,8 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
 	int rc;
 	int old_page_state = 0;
 	struct anon_vma *anon_vma = NULL;
+	bool src_deferred_split = false;
+	bool src_partially_mapped = false;
 	struct list_head *prev;
 
 	__migrate_folio_extract(dst, &old_page_state, &anon_vma);
@@ -1373,6 +1375,12 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
 		goto out_unlock_both;
 	}
 
+	if (folio_order(src) > 1 &&
+	    !data_race(list_empty(&src->_deferred_list))) {
+		src_deferred_split = true;
+		src_partially_mapped = folio_test_partially_mapped(src);
+	}
+
 	rc = move_to_new_folio(dst, src, mode);
 	if (rc)
 		goto out;
@@ -1393,6 +1401,15 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
 	if (old_page_state & PAGE_WAS_MAPPED)
 		remove_migration_ptes(src, dst, 0);
 
+	/*
+	 * Requeue the destination folio on the deferred split queue if
+	 * the source was on the queue.  The source is unqueued in
+	 * __folio_migrate_mapping(), so we recorded the state from
+	 * before move_to_new_folio().
+	 */
+	if (src_deferred_split)
+		deferred_split_folio(dst, src_partially_mapped);
+
 out_unlock_both:
 	folio_unlock(dst);
 	folio_set_owner_migrate_reason(dst, reason);
-- 
2.52.0
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by Wei Yang 3 weeks, 4 days ago
On Thu, Mar 12, 2026 at 03:47:23AM -0700, Usama Arif wrote:
>During folio migration, __folio_migrate_mapping() removes the source
>folio from the deferred split queue, but the destination folio is never
>re-queued.  This causes underutilized THPs to escape the shrinker after
>NUMA migration, since they silently drop off the deferred split list.
>
>Fix this by recording whether the source folio was on the deferred split
>queue and its partially mapped state before move_to_new_folio() unqueues
>it, and re-queuing the destination folio after a successful migration if
>it was.
>
>By the time migrate_folio_move() runs, partially mapped folios without a
>pin have already been split by migrate_pages_batch().  So only two cases
>remain on the deferred list at this point:
>  1. Partially mapped folios with a pin (split failed).
>  2. Fully mapped but potentially underused folios.
>The recorded partially_mapped state is forwarded to deferred_split_folio()
>so that the destination folio is correctly re-queued in both cases.
>
>Reported-by: Johannes Weiner <hannes@cmpxchg.org>
>Fixes: dafff3f4c850 ("mm: split underused THPs")
>Acked-by: Zi Yan <ziy@nvidia.com>
>Acked-by: David Hildenbrand (Arm) <david@kernel.org>
>Signed-off-by: Usama Arif <usama.arif@linux.dev>

LGTM, thanks.

Reviewed-by: Wei Yang <richard.weiyang@gmail.com>

-- 
Wei Yang
Help you, Help me
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by SeongJae Park 3 weeks, 4 days ago
On Thu, 12 Mar 2026 03:47:23 -0700 Usama Arif <usama.arif@linux.dev> wrote:

> During folio migration, __folio_migrate_mapping() removes the source
> folio from the deferred split queue, but the destination folio is never
> re-queued.  This causes underutilized THPs to escape the shrinker after
> NUMA migration, since they silently drop off the deferred split list.
> 
> Fix this by recording whether the source folio was on the deferred split
> queue and its partially mapped state before move_to_new_folio() unqueues
> it, and re-queuing the destination folio after a successful migration if
> it was.
> 
> By the time migrate_folio_move() runs, partially mapped folios without a
> pin have already been split by migrate_pages_batch().  So only two cases
> remain on the deferred list at this point:
>   1. Partially mapped folios with a pin (split failed).
>   2. Fully mapped but potentially underused folios.
> The recorded partially_mapped state is forwarded to deferred_split_folio()
> so that the destination folio is correctly re-queued in both cases.
> 
> Reported-by: Johannes Weiner <hannes@cmpxchg.org>
> Fixes: dafff3f4c850 ("mm: split underused THPs")

Seems the commit is merged in 6.12.  And I assume the user impact on
THP-shrinker enabled systems is visible.  If so, should we Cc stable@ ?

> Acked-by: Zi Yan <ziy@nvidia.com>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Usama Arif <usama.arif@linux.dev>

Acked-by: SeongJae Park <sj@kernel.org>


Thanks,
SJ

[...]
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by Andrew Morton 3 weeks, 4 days ago
On Thu, 12 Mar 2026 17:16:30 -0700 SeongJae Park <sj@kernel.org> wrote:

> > By the time migrate_folio_move() runs, partially mapped folios without a
> > pin have already been split by migrate_pages_batch().  So only two cases
> > remain on the deferred list at this point:
> >   1. Partially mapped folios with a pin (split failed).
> >   2. Fully mapped but potentially underused folios.
> > The recorded partially_mapped state is forwarded to deferred_split_folio()
> > so that the destination folio is correctly re-queued in both cases.
> > 
> > Reported-by: Johannes Weiner <hannes@cmpxchg.org>
> > Fixes: dafff3f4c850 ("mm: split underused THPs")
> 
> Seems the commit is merged in 6.12.  And I assume the user impact on
> THP-shrinker enabled systems is visible.  If so, should we Cc stable@ ?

I think the user impact should be visible to backport, but the
changelog is elusive on details?
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by Usama Arif 3 weeks, 4 days ago

On 13/03/2026 03:52, Andrew Morton wrote:
> On Thu, 12 Mar 2026 17:16:30 -0700 SeongJae Park <sj@kernel.org> wrote:
> 
>>> By the time migrate_folio_move() runs, partially mapped folios without a
>>> pin have already been split by migrate_pages_batch().  So only two cases
>>> remain on the deferred list at this point:
>>>   1. Partially mapped folios with a pin (split failed).
>>>   2. Fully mapped but potentially underused folios.
>>> The recorded partially_mapped state is forwarded to deferred_split_folio()
>>> so that the destination folio is correctly re-queued in both cases.
>>>
>>> Reported-by: Johannes Weiner <hannes@cmpxchg.org>
>>> Fixes: dafff3f4c850 ("mm: split underused THPs")
>>
>> Seems the commit is merged in 6.12.  And I assume the user impact on
>> THP-shrinker enabled systems is visible.  If so, should we Cc stable@ ?
> 
> I think the user impact should be visible to backport, but the
> changelog is elusive on details?
> 


The original patches added THPs to deferred_list at fault/collapse, they
got removed but not added back to the list after migration.
This patch adds them to the deferred_list on migration. The user would
not expect the THPs to get removed from deferred_list on migration, so
this fixes user expectations.

I have CC-ed stable@vger.kernel.org to this email. Should I resend the patch
with CC stable in commit message?
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by Andrew Morton 3 weeks, 2 days ago
On Fri, 13 Mar 2026 13:40:29 +0300 Usama Arif <usama.arif@linux.dev> wrote:

> 
> 
> On 13/03/2026 03:52, Andrew Morton wrote:
> > On Thu, 12 Mar 2026 17:16:30 -0700 SeongJae Park <sj@kernel.org> wrote:
> > 
> >>> By the time migrate_folio_move() runs, partially mapped folios without a
> >>> pin have already been split by migrate_pages_batch().  So only two cases
> >>> remain on the deferred list at this point:
> >>>   1. Partially mapped folios with a pin (split failed).
> >>>   2. Fully mapped but potentially underused folios.
> >>> The recorded partially_mapped state is forwarded to deferred_split_folio()
> >>> so that the destination folio is correctly re-queued in both cases.
> >>>
> >>> Reported-by: Johannes Weiner <hannes@cmpxchg.org>
> >>> Fixes: dafff3f4c850 ("mm: split underused THPs")
> >>
> >> Seems the commit is merged in 6.12.  And I assume the user impact on
> >> THP-shrinker enabled systems is visible.  If so, should we Cc stable@ ?
> > 
> > I think the user impact should be visible to backport, but the
> > changelog is elusive on details?
> > 
> 
> 
> The original patches added THPs to deferred_list at fault/collapse, they
> got removed but not added back to the list after migration.
> This patch adds them to the deferred_list on migration. The user would
> not expect the THPs to get removed from deferred_list on migration, so
> this fixes user expectations.

Maybe users just won't notice?

If we can't identify any benefit to userspace then I don't think this
patch meets the criteria for backporting.

> I have CC-ed stable@vger.kernel.org to this email. Should I resend the patch
> with CC stable in commit message?

That's OK, I update changelogs.  A lot.
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by SeongJae Park 3 weeks, 2 days ago
On Sat, 14 Mar 2026 15:40:42 -0700 Andrew Morton <akpm@linux-foundation.org> wrote:

> On Fri, 13 Mar 2026 13:40:29 +0300 Usama Arif <usama.arif@linux.dev> wrote:
> 
> > 
> > 
> > On 13/03/2026 03:52, Andrew Morton wrote:
> > > On Thu, 12 Mar 2026 17:16:30 -0700 SeongJae Park <sj@kernel.org> wrote:
> > > 
> > >>> By the time migrate_folio_move() runs, partially mapped folios without a
> > >>> pin have already been split by migrate_pages_batch().  So only two cases
> > >>> remain on the deferred list at this point:
> > >>>   1. Partially mapped folios with a pin (split failed).
> > >>>   2. Fully mapped but potentially underused folios.
> > >>> The recorded partially_mapped state is forwarded to deferred_split_folio()
> > >>> so that the destination folio is correctly re-queued in both cases.
> > >>>
> > >>> Reported-by: Johannes Weiner <hannes@cmpxchg.org>
> > >>> Fixes: dafff3f4c850 ("mm: split underused THPs")
> > >>
> > >> Seems the commit is merged in 6.12.  And I assume the user impact on
> > >> THP-shrinker enabled systems is visible.  If so, should we Cc stable@ ?
> > > 
> > > I think the user impact should be visible to backport, but the
> > > changelog is elusive on details?
> > > 
> > 
> > 
> > The original patches added THPs to deferred_list at fault/collapse, they
> > got removed but not added back to the list after migration.
> > This patch adds them to the deferred_list on migration. The user would
> > not expect the THPs to get removed from deferred_list on migration, so
> > this fixes user expectations.
> 
> Maybe users just won't notice?

My guess of the user-visible consequence was like following.  Because THPs are
removed from the deferred_list, THP shinker cannot split the underutilized THPs
in time.  As a result, users will show less free memory than before.  I believe
I might be wrong and Usama can correct me in the case.


Thanks,
SJ

[...]
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by Andrew Morton 3 weeks, 2 days ago
On Sat, 14 Mar 2026 17:05:54 -0700 SeongJae Park <sj@kernel.org> wrote:

>  Because THPs are
> removed from the deferred_list, THP shinker cannot split the underutilized THPs
> in time.  As a result, users will show less free memory than before.

That'll do, thanks ;)

Pasted, added cc:stable.  It's been there since 6.12 so I don't see a
need to rush this in, so I won't move this into mm-hotfixes - it'll go
into mainline for 7.1-rc1 after which -stable should pick it up.
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by David Hildenbrand (Arm) 2 weeks, 4 days ago
On 3/15/26 01:23, Andrew Morton wrote:
> On Sat, 14 Mar 2026 17:05:54 -0700 SeongJae Park <sj@kernel.org> wrote:
> 
>>  Because THPs are
>> removed from the deferred_list, THP shinker cannot split the underutilized THPs
>> in time.  As a result, users will show less free memory than before.
> 
> That'll do, thanks ;)
> 
> Pasted, added cc:stable.  It's been there since 6.12 so I don't see a
> need to rush this in, so I won't move this into mm-hotfixes - it'll go
> into mainline for 7.1-rc1 after which -stable should pick it up.

Makes sense. I guess using the partially-mapped is only a slight
problem, because we usually try to split partially-mapped before migrating.

So it's mostly about over-allocated THPs (mostly 0) not getting scanned
and split+reclaimed after they were migrated.

Under memory pressure without swap, that might create a user-visible
problem, especially when many such THPs are migrated before being
scanned for zeropages that can be reclaimed.

-- 
Cheers,

David
Re: [PATCH v3] mm: migrate: requeue destination folio on deferred split queue
Posted by Johannes Weiner 3 weeks, 5 days ago
On Thu, Mar 12, 2026 at 03:47:23AM -0700, Usama Arif wrote:
> During folio migration, __folio_migrate_mapping() removes the source
> folio from the deferred split queue, but the destination folio is never
> re-queued.  This causes underutilized THPs to escape the shrinker after
> NUMA migration, since they silently drop off the deferred split list.
> 
> Fix this by recording whether the source folio was on the deferred split
> queue and its partially mapped state before move_to_new_folio() unqueues
> it, and re-queuing the destination folio after a successful migration if
> it was.
> 
> By the time migrate_folio_move() runs, partially mapped folios without a
> pin have already been split by migrate_pages_batch().  So only two cases
> remain on the deferred list at this point:
>   1. Partially mapped folios with a pin (split failed).
>   2. Fully mapped but potentially underused folios.
> The recorded partially_mapped state is forwarded to deferred_split_folio()
> so that the destination folio is correctly re-queued in both cases.
> 
> Reported-by: Johannes Weiner <hannes@cmpxchg.org>
> Fixes: dafff3f4c850 ("mm: split underused THPs")
> Acked-by: Zi Yan <ziy@nvidia.com>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Usama Arif <usama.arif@linux.dev>

Acked-by: Johannes Weiner <hannes@cmpxchg.org>