aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c38
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. */
5682static int __alloc_contig_migrate_range(unsigned long start, unsigned long end) 5682static 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;