aboutsummaryrefslogtreecommitdiffstats
path: root/mm/compaction.c
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2015-09-08 18:02:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-08 18:35:28 -0400
commit9fcd6d2e052eef525e94a9ae58dbe7ed4df4f5a7 (patch)
tree73352bbd22c199a0dcbd7a1a06f3bd5f5a4111ad /mm/compaction.c
parent29c0dde830f8c08ceacf2d3edf6dc8ddd9a9c3c4 (diff)
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 <vbabka@suse.cz> Cc: Minchan Kim <minchan@kernel.org> Cc: Mel Gorman <mgorman@suse.de> Acked-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> Acked-by: Michal Nazarewicz <mina86@mina86.com> Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Christoph Lameter <cl@linux.com> Cc: Rik van Riel <riel@redhat.com> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/compaction.c')
-rw-r--r--mm/compaction.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index 1ccb015ab1eb..8f64d3533990 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -437,6 +437,24 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
437 437
438 if (!valid_page) 438 if (!valid_page)
439 valid_page = page; 439 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
440 if (!PageBuddy(page)) 458 if (!PageBuddy(page))
441 goto isolate_fail; 459 goto isolate_fail;
442 460
@@ -496,6 +514,13 @@ isolate_fail:
496 514
497 } 515 }
498 516
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
499 trace_mm_compaction_isolate_freepages(*start_pfn, blockpfn, 524 trace_mm_compaction_isolate_freepages(*start_pfn, blockpfn,
500 nr_scanned, total_isolated); 525 nr_scanned, total_isolated);
501 526