diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 628968c1ccf4..44c56049edf9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -5679,7 +5679,8 @@ __alloc_contig_migrate_alloc(struct page *page, unsigned long private, | |||
5679 | } | 5679 | } |
5680 | 5680 | ||
5681 | /* [start, end) must belong to a single zone. */ | 5681 | /* [start, end) must belong to a single zone. */ |
5682 | static int __alloc_contig_migrate_range(unsigned long start, unsigned long end) | 5682 | static int __alloc_contig_migrate_range(struct compact_control *cc, |
5683 | unsigned long start, unsigned long end) | ||
5683 | { | 5684 | { |
5684 | /* This function is based on compact_zone() from compaction.c. */ | 5685 | /* This function is based on compact_zone() from compaction.c. */ |
5685 | 5686 | ||
@@ -5687,25 +5688,17 @@ static int __alloc_contig_migrate_range(unsigned long start, unsigned long end) | |||
5687 | unsigned int tries = 0; | 5688 | unsigned int tries = 0; |
5688 | int ret = 0; | 5689 | int ret = 0; |
5689 | 5690 | ||
5690 | struct compact_control cc = { | ||
5691 | .nr_migratepages = 0, | ||
5692 | .order = -1, | ||
5693 | .zone = page_zone(pfn_to_page(start)), | ||
5694 | .sync = true, | ||
5695 | }; | ||
5696 | INIT_LIST_HEAD(&cc.migratepages); | ||
5697 | |||
5698 | migrate_prep_local(); | 5691 | migrate_prep_local(); |
5699 | 5692 | ||
5700 | while (pfn < end || !list_empty(&cc.migratepages)) { | 5693 | while (pfn < end || !list_empty(&cc->migratepages)) { |
5701 | if (fatal_signal_pending(current)) { | 5694 | if (fatal_signal_pending(current)) { |
5702 | ret = -EINTR; | 5695 | ret = -EINTR; |
5703 | break; | 5696 | break; |
5704 | } | 5697 | } |
5705 | 5698 | ||
5706 | if (list_empty(&cc.migratepages)) { | 5699 | if (list_empty(&cc->migratepages)) { |
5707 | cc.nr_migratepages = 0; | 5700 | cc->nr_migratepages = 0; |
5708 | pfn = isolate_migratepages_range(cc.zone, &cc, | 5701 | pfn = isolate_migratepages_range(cc->zone, cc, |
5709 | pfn, end); | 5702 | pfn, end); |
5710 | if (!pfn) { | 5703 | if (!pfn) { |
5711 | ret = -EINTR; | 5704 | ret = -EINTR; |
@@ -5717,14 +5710,14 @@ static int __alloc_contig_migrate_range(unsigned long start, unsigned long end) | |||
5717 | break; | 5710 | break; |
5718 | } | 5711 | } |
5719 | 5712 | ||
5720 | reclaim_clean_pages_from_list(cc.zone, &cc.migratepages); | 5713 | reclaim_clean_pages_from_list(cc->zone, &cc->migratepages); |
5721 | 5714 | ||
5722 | ret = migrate_pages(&cc.migratepages, | 5715 | ret = migrate_pages(&cc->migratepages, |
5723 | __alloc_contig_migrate_alloc, | 5716 | __alloc_contig_migrate_alloc, |
5724 | 0, false, MIGRATE_SYNC); | 5717 | 0, false, MIGRATE_SYNC); |
5725 | } | 5718 | } |
5726 | 5719 | ||
5727 | putback_lru_pages(&cc.migratepages); | 5720 | putback_lru_pages(&cc->migratepages); |
5728 | return ret > 0 ? 0 : ret; | 5721 | return ret > 0 ? 0 : ret; |
5729 | } | 5722 | } |
5730 | 5723 | ||
@@ -5803,6 +5796,15 @@ int alloc_contig_range(unsigned long start, unsigned long end, | |||
5803 | unsigned long outer_start, outer_end; | 5796 | unsigned long outer_start, outer_end; |
5804 | int ret = 0, order; | 5797 | int ret = 0, order; |
5805 | 5798 | ||
5799 | struct compact_control cc = { | ||
5800 | .nr_migratepages = 0, | ||
5801 | .order = -1, | ||
5802 | .zone = page_zone(pfn_to_page(start)), | ||
5803 | .sync = true, | ||
5804 | .ignore_skip_hint = true, | ||
5805 | }; | ||
5806 | INIT_LIST_HEAD(&cc.migratepages); | ||
5807 | |||
5806 | /* | 5808 | /* |
5807 | * What we do here is we mark all pageblocks in range as | 5809 | * What we do here is we mark all pageblocks in range as |
5808 | * MIGRATE_ISOLATE. Because pageblock and max order pages may | 5810 | * MIGRATE_ISOLATE. Because pageblock and max order pages may |
@@ -5832,7 +5834,7 @@ int alloc_contig_range(unsigned long start, unsigned long end, | |||
5832 | if (ret) | 5834 | if (ret) |
5833 | goto done; | 5835 | goto done; |
5834 | 5836 | ||
5835 | ret = __alloc_contig_migrate_range(start, end); | 5837 | ret = __alloc_contig_migrate_range(&cc, start, end); |
5836 | if (ret) | 5838 | if (ret) |
5837 | goto done; | 5839 | goto done; |
5838 | 5840 | ||
@@ -5881,7 +5883,7 @@ int alloc_contig_range(unsigned long start, unsigned long end, | |||
5881 | __reclaim_pages(zone, GFP_HIGHUSER_MOVABLE, end-start); | 5883 | __reclaim_pages(zone, GFP_HIGHUSER_MOVABLE, end-start); |
5882 | 5884 | ||
5883 | /* Grab isolated pages from freelists. */ | 5885 | /* Grab isolated pages from freelists. */ |
5884 | outer_end = isolate_freepages_range(outer_start, end); | 5886 | outer_end = isolate_freepages_range(&cc, outer_start, end); |
5885 | if (!outer_end) { | 5887 | if (!outer_end) { |
5886 | ret = -EBUSY; | 5888 | ret = -EBUSY; |
5887 | goto done; | 5889 | goto done; |