Re: [PATCH 2/4] mm: compaction: support non-movable compaction for pageblock requests
From: Zi Yan
Date: Wed Jul 01 2026 - 21:48:11 EST
On Fri Jun 26, 2026 at 2:21 PM EDT, Johannes Weiner wrote:
> While trying to fix a reclaim storm in defrag_mode, I noticed that
> non-movable direct compaction is extremely inefficient.
>
> When searching for space to evacuate, compaction only allows blocks of
> the same type as the incoming request. This is to prevent migratetype
> pollution, where a small non-movable request frees space in a movable
> block and provokes the allocator to fall back and pollute it.
>
> This protection is reasonable on one hand, but the downside is that it
> makes non-movable direct compaction nearly useless: if we get the type
> annotations right, by definition there aren't any movable pages inside
> the non-movable blocks it is allowed to scan.
>
> With defrag_mode, the goal is the production of whole blocks, which
> are essentially type neutral: __rmqueue_claim() will convert them
> wholesale on alloc. This makes type mixing and pollution a non-issue.
>
> Fix the pollution gates to take the requested order into account, and
> allow whole-block requests to scan blocks of other types.
>
> The only exception is CMA blocks. That type is sticky and these blocks
> cannot be claimed to other types. Continue to be strict with them, and
> allow only explicit ALLOC_CMA requests and kcompactd to evacuate them.
>
> Signed-off-by: Johannes Weiner <hannes@xxxxxxxxxxx>
> ---
> mm/compaction.c | 35 ++++++++++++++++++++++++++++-------
> 1 file changed, 28 insertions(+), 7 deletions(-)
>
<snip>
> +
> + /*
> + * Prevent small unmovable/reclaimable requests from polluting
"small" here means smaller than pageblock_order requests? If yes, it is
better to spell it out to prevent confusion.
> + * movable blocks through fallbacks. Whole-block production is
> + * exempt as the allocator claims and converts these.
> + */
> + if (cc->migratetype == MIGRATE_MOVABLE || cc->order >= pageblock_order)
> return is_migrate_movable(block_mt);
> else
> return block_mt == cc->migratetype;
> @@ -1974,12 +1995,12 @@ static unsigned long fast_find_migrateblock(struct compact_control *cc)
> return pfn;
>
> /*
> - * Only allow kcompactd and direct requests for movable pages to
> - * quickly clear out a MOVABLE pageblock for allocation. This
> - * reduces the risk that a large movable pageblock is freed for
> - * an unmovable/reclaimable small allocation.
> + * Prevent small unmovable/reclaimable requests from polluting
This "small" as well.
> + * movable blocks through fallbacks. Whole-block production is
> + * exempt as the allocator claims and converts these.
> */
> - if (cc->direct_compaction && cc->migratetype != MIGRATE_MOVABLE)
> + if (cc->direct_compaction && cc->migratetype != MIGRATE_MOVABLE &&
> + cc->order < pageblock_order)
> return pfn;
>
> /*
--
Best Regards,
Yan, Zi