diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ca58bfcdadac..2f6d30db4c94 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -6725,8 +6725,12 @@ int alloc_contig_range(unsigned long start, unsigned long end, | |||
6725 | if (ret) | 6725 | if (ret) |
6726 | return ret; | 6726 | return ret; |
6727 | 6727 | ||
6728 | /* | ||
6729 | * In case of -EBUSY, we'd like to know which page causes problem. | ||
6730 | * So, just fall through. We will check it in test_pages_isolated(). | ||
6731 | */ | ||
6728 | ret = __alloc_contig_migrate_range(&cc, start, end); | 6732 | ret = __alloc_contig_migrate_range(&cc, start, end); |
6729 | if (ret) | 6733 | if (ret && ret != -EBUSY) |
6730 | goto done; | 6734 | goto done; |
6731 | 6735 | ||
6732 | /* | 6736 | /* |
@@ -6753,12 +6757,25 @@ int alloc_contig_range(unsigned long start, unsigned long end, | |||
6753 | outer_start = start; | 6757 | outer_start = start; |
6754 | while (!PageBuddy(pfn_to_page(outer_start))) { | 6758 | while (!PageBuddy(pfn_to_page(outer_start))) { |
6755 | if (++order >= MAX_ORDER) { | 6759 | if (++order >= MAX_ORDER) { |
6756 | ret = -EBUSY; | 6760 | outer_start = start; |
6757 | goto done; | 6761 | break; |
6758 | } | 6762 | } |
6759 | outer_start &= ~0UL << order; | 6763 | outer_start &= ~0UL << order; |
6760 | } | 6764 | } |
6761 | 6765 | ||
6766 | if (outer_start != start) { | ||
6767 | order = page_order(pfn_to_page(outer_start)); | ||
6768 | |||
6769 | /* | ||
6770 | * outer_start page could be small order buddy page and | ||
6771 | * it doesn't include start page. Adjust outer_start | ||
6772 | * in this case to report failed page properly | ||
6773 | * on tracepoint in test_pages_isolated() | ||
6774 | */ | ||
6775 | if (outer_start + (1UL << order) <= start) | ||
6776 | outer_start = start; | ||
6777 | } | ||
6778 | |||
6762 | /* Make sure the range is really isolated. */ | 6779 | /* Make sure the range is really isolated. */ |
6763 | if (test_pages_isolated(outer_start, end, false)) { | 6780 | if (test_pages_isolated(outer_start, end, false)) { |
6764 | pr_info("%s: [%lx, %lx) PFNs busy\n", | 6781 | pr_info("%s: [%lx, %lx) PFNs busy\n", |