Skip to content

Commit

Permalink
mm: page_alloc: claim blocks during compaction capturing
Browse files Browse the repository at this point in the history
When capturing a whole block, update the migratetype accordingly. For
example, a THP allocation might capture an unmovable block. If the THP
gets split and partially freed later, the remainder should group up
with movable allocations.

Signed-off-by: Johannes Weiner <[email protected]>
  • Loading branch information
hnaz committed Mar 9, 2023
1 parent 18b6c98 commit 9382ca4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 18 deletions.
1 change: 1 addition & 0 deletions mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ struct compact_control {
*/
struct capture_control {
struct compact_control *cc;
int migratetype;
struct page *page;
};

Expand Down
42 changes: 24 additions & 18 deletions mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,17 @@ void set_pageblock_migratetype(struct page *page, int migratetype)
page_to_pfn(page), MIGRATETYPE_MASK);
}

static void change_pageblock_range(struct page *pageblock_page,
int start_order, int migratetype)
{
int nr_pageblocks = 1 << (start_order - pageblock_order);

while (nr_pageblocks--) {
set_pageblock_migratetype(pageblock_page, migratetype);
pageblock_page += pageblock_nr_pages;
}
}

#ifdef CONFIG_DEBUG_VM
static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
{
Expand Down Expand Up @@ -962,14 +973,19 @@ compaction_capture(struct capture_control *capc, struct page *page,
is_migrate_isolate(migratetype))
return false;

/*
* Do not let lower order allocations pollute a movable pageblock.
* This might let an unmovable request use a reclaimable pageblock
* and vice-versa but no more than normal fallback logic which can
* have trouble finding a high-order free page.
*/
if (order < pageblock_order && migratetype == MIGRATE_MOVABLE)
if (order >= pageblock_order) {
migratetype = capc->migratetype;
change_pageblock_range(page, order, migratetype);
} else if (migratetype == MIGRATE_MOVABLE) {
/*
* Do not let lower order allocations pollute a
* movable pageblock. This might let an unmovable
* request use a reclaimable pageblock and vice-versa
* but no more than normal fallback logic which can
* have trouble finding a high-order free page.
*/
return false;
}

capc->page = page;
return true;
Expand Down Expand Up @@ -2674,17 +2690,6 @@ int move_freepages_block(struct zone *zone, struct page *page,
old_mt, new_mt, num_movable);
}

static void change_pageblock_range(struct page *pageblock_page,
int start_order, int migratetype)
{
int nr_pageblocks = 1 << (start_order - pageblock_order);

while (nr_pageblocks--) {
set_pageblock_migratetype(pageblock_page, migratetype);
pageblock_page += pageblock_nr_pages;
}
}

/*
* When we are falling back to another migratetype during allocation, try to
* steal extra free pages from the same pageblocks to satisfy further
Expand Down Expand Up @@ -4481,6 +4486,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
unsigned long pflags;
unsigned int noreclaim_flag;
struct capture_control capc = {
.migratetype = ac->migratetype,
.page = NULL,
};

Expand Down

0 comments on commit 9382ca4

Please sign in to comment.