[RFC PATCH 5/5] mm/page_alloc: claim blocks captured for non-movable use

From: Rik van Riel

Date: Tue Oct 06 2026 - 22:14:49 EST


compaction_capture() hands any merged block to the compacting task
with no type change, except it refuses a movable block to a
non-movable request below pageblock order. A non-movable request
capturing a whole movable block leaves non-movable content in a
movable-typed block.

Make a non-movable capture claim a movable block: convert it to
the request. A partial block cannot be retyped, so the refusal
below pageblock order stays; reaching the conversion means a
whole block. A movable capture steals: it takes the pages and
leaves the type alone.

Assisted-by: LLM
Signed-off-by: Rik van Riel <riel@xxxxxxxxxxx>
---
mm/page_alloc.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 16d3594d913a0..edb69d8a74c73 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -728,6 +728,9 @@ static inline struct capture_control *task_capc(struct zone *zone)
capc->zone == zone ? capc : NULL;
}

+static void change_pageblock_range(struct page *pageblock_page,
+ int start_order, int migratetype);
+
static inline bool
compaction_capture(struct capture_control *capc, struct page *page,
int order, int migratetype)
@@ -751,6 +754,19 @@ compaction_capture(struct capture_control *capc, struct page *page,
capc->migratetype != MIGRATE_MOVABLE)
return false;

+ /*
+ * A non-movable capture claims a movable block: convert it to
+ * the request. A movable capture steals: take the pages and
+ * leave the type alone. Partial movable blocks returned above,
+ * so reaching here means a whole block.
+ */
+ if (capc->migratetype != MIGRATE_MOVABLE &&
+ migratetype == MIGRATE_MOVABLE) {
+ change_pageblock_range(page, order, capc->migratetype);
+ /* Converted whole, so no fragmentation to report below. */
+ migratetype = capc->migratetype;
+ }
+
if (migratetype != capc->migratetype)
trace_mm_page_alloc_extfrag(page, capc->order, order,
capc->migratetype, migratetype);
--
2.53.0-Meta