Re: [PATCH] mm/migrate: wake kcompactd when huge folio migration fails in numa balancing
From: Zi Yan
Date: Thu Oct 22 2026 - 15:05:21 EST
On Thu Oct 22, 2026 at 1:25 PM EDT, Joshua Hahn wrote:
> NUMA balancing migrates a misplaced folio if migrate_balanced_pgdat()
> finds enough headroom on the destination node. For large folios, it then
> allocates a folio from the destination with GFP_TRANSHUGE_LIGHT, which
> wakes up neither kswapd nor kcompactd. This means a hot large folio
> trying to promote to a fragmented destination may never succeed in
> promotion even after repeated retries.
>
> Wake kcompactd on the target node when the destination allocation fails
> for a large folio. Don't wake kswapd, since this path can only be
> reached if there is enough free memory to service the allocation, but it
> is too fragmented to serve the large folio allocation.
>
> This patch has been A/B tested on tiered Meta systems (DRAM + CXL)
> running identical cacheing workloads. Without this patch, we accumulate
> around 4.5k failed THP migrations over the span of a day, while the host
> with this patch accumulates only about 80.
Is proactive compaction enabled? If yes, why does it not help?
>
> Those migration differences leads to about 25% reduced CXL bandwidth
> usage after applying this patch.
>
> Signed-off-by: Joshua Hahn <joshua.hahnjy@xxxxxxxxx>
> ---
> mm/migrate.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/mm/migrate.c b/mm/migrate.c
> index 7bdcdb57652f8..67364fe0851c0 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -2671,6 +2671,7 @@ static struct folio *alloc_misplaced_dst_folio(struct folio *src,
> int nid = (int) data;
> int order = folio_order(src);
> gfp_t gfp = __GFP_THISNODE;
> + struct folio *dst;
>
> if (order > 0)
> gfp |= GFP_TRANSHUGE_LIGHT;
> @@ -2679,7 +2680,17 @@ static struct folio *alloc_misplaced_dst_folio(struct folio *src,
> __GFP_NOWARN;
> gfp &= ~__GFP_RECLAIM;
> }
> - return __folio_alloc_node(gfp, order, nid);
> +
> + dst = __folio_alloc_node(gfp, order, nid);
> +
> + /*
> + * A node with enough free memory might still be too fragmented to serve
> + * a large folio. Wake kcompactd to help the next huge folio migration.
> + */
> + if (!dst && order > 0)
> + wakeup_kcompactd(NODE_DATA(nid), order, gfp_zone(gfp));
> +
> + return dst;
> }
>
> /*
--
Best Regards,
Yan, Zi