Skip to content

Commit 9fcd6d2

Browse files
tehcastertorvalds
authored andcommitted
mm, compaction: skip compound pages by order in free scanner
The compaction free scanner is looking for PageBuddy() pages and skipping all others. For large compound pages such as THP or hugetlbfs, we can save a lot of iterations if we skip them at once using their compound_order(). This is generally unsafe and we can read a bogus value of order due to a race, but if we are careful, the only danger is skipping too much. When tested with stress-highalloc from mmtests on 4GB system with 1GB hugetlbfs pages, the vmstat compact_free_scanned count decreased by at least 15%. Signed-off-by: Vlastimil Babka <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Mel Gorman <[email protected]> Acked-by: Joonsoo Kim <[email protected]> Acked-by: Michal Nazarewicz <[email protected]> Cc: Naoya Horiguchi <[email protected]> Cc: Christoph Lameter <[email protected]> Cc: Rik van Riel <[email protected]> Cc: David Rientjes <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 29c0dde commit 9fcd6d2

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

mm/compaction.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,24 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
437437

438438
if (!valid_page)
439439
valid_page = page;
440+
441+
/*
442+
* For compound pages such as THP and hugetlbfs, we can save
443+
* potentially a lot of iterations if we skip them at once.
444+
* The check is racy, but we can consider only valid values
445+
* and the only danger is skipping too much.
446+
*/
447+
if (PageCompound(page)) {
448+
unsigned int comp_order = compound_order(page);
449+
450+
if (likely(comp_order < MAX_ORDER)) {
451+
blockpfn += (1UL << comp_order) - 1;
452+
cursor += (1UL << comp_order) - 1;
453+
}
454+
455+
goto isolate_fail;
456+
}
457+
440458
if (!PageBuddy(page))
441459
goto isolate_fail;
442460

@@ -496,6 +514,13 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
496514

497515
}
498516

517+
/*
518+
* There is a tiny chance that we have read bogus compound_order(),
519+
* so be careful to not go outside of the pageblock.
520+
*/
521+
if (unlikely(blockpfn > end_pfn))
522+
blockpfn = end_pfn;
523+
499524
trace_mm_compaction_isolate_freepages(*start_pfn, blockpfn,
500525
nr_scanned, total_isolated);
501526

0 commit comments

Comments
 (0)