|
@@ -437,6 +437,24 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
|
|
|
|
|
|
if (!valid_page)
|
|
|
valid_page = page;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * For compound pages such as THP and hugetlbfs, we can save
|
|
|
+ * potentially a lot of iterations if we skip them at once.
|
|
|
+ * The check is racy, but we can consider only valid values
|
|
|
+ * and the only danger is skipping too much.
|
|
|
+ */
|
|
|
+ if (PageCompound(page)) {
|
|
|
+ unsigned int comp_order = compound_order(page);
|
|
|
+
|
|
|
+ if (likely(comp_order < MAX_ORDER)) {
|
|
|
+ blockpfn += (1UL << comp_order) - 1;
|
|
|
+ cursor += (1UL << comp_order) - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ goto isolate_fail;
|
|
|
+ }
|
|
|
+
|
|
|
if (!PageBuddy(page))
|
|
|
goto isolate_fail;
|
|
|
|
|
@@ -496,6 +514,13 @@ isolate_fail:
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * There is a tiny chance that we have read bogus compound_order(),
|
|
|
+ * so be careful to not go outside of the pageblock.
|
|
|
+ */
|
|
|
+ if (unlikely(blockpfn > end_pfn))
|
|
|
+ blockpfn = end_pfn;
|
|
|
+
|
|
|
trace_mm_compaction_isolate_freepages(*start_pfn, blockpfn,
|
|
|
nr_scanned, total_isolated);
|
|
|
|