diff options
Diffstat (limited to 'mm/compaction.c')
-rw-r--r-- | mm/compaction.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/mm/compaction.c b/mm/compaction.c index c62bd063d766..05ccb4cc0bdb 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/sysctl.h> | 15 | #include <linux/sysctl.h> |
16 | #include <linux/sysfs.h> | 16 | #include <linux/sysfs.h> |
17 | #include <linux/balloon_compaction.h> | 17 | #include <linux/balloon_compaction.h> |
18 | #include <linux/page-isolation.h> | ||
18 | #include "internal.h" | 19 | #include "internal.h" |
19 | 20 | ||
20 | #ifdef CONFIG_COMPACTION | 21 | #ifdef CONFIG_COMPACTION |
@@ -85,7 +86,7 @@ static inline bool isolation_suitable(struct compact_control *cc, | |||
85 | static void __reset_isolation_suitable(struct zone *zone) | 86 | static void __reset_isolation_suitable(struct zone *zone) |
86 | { | 87 | { |
87 | unsigned long start_pfn = zone->zone_start_pfn; | 88 | unsigned long start_pfn = zone->zone_start_pfn; |
88 | unsigned long end_pfn = zone->zone_start_pfn + zone->spanned_pages; | 89 | unsigned long end_pfn = zone_end_pfn(zone); |
89 | unsigned long pfn; | 90 | unsigned long pfn; |
90 | 91 | ||
91 | zone->compact_cached_migrate_pfn = start_pfn; | 92 | zone->compact_cached_migrate_pfn = start_pfn; |
@@ -215,7 +216,10 @@ static bool suitable_migration_target(struct page *page) | |||
215 | int migratetype = get_pageblock_migratetype(page); | 216 | int migratetype = get_pageblock_migratetype(page); |
216 | 217 | ||
217 | /* Don't interfere with memory hot-remove or the min_free_kbytes blocks */ | 218 | /* Don't interfere with memory hot-remove or the min_free_kbytes blocks */ |
218 | if (migratetype == MIGRATE_ISOLATE || migratetype == MIGRATE_RESERVE) | 219 | if (migratetype == MIGRATE_RESERVE) |
220 | return false; | ||
221 | |||
222 | if (is_migrate_isolate(migratetype)) | ||
219 | return false; | 223 | return false; |
220 | 224 | ||
221 | /* If the page is a large free page, then allow migration */ | 225 | /* If the page is a large free page, then allow migration */ |
@@ -611,8 +615,7 @@ check_compact_cluster: | |||
611 | continue; | 615 | continue; |
612 | 616 | ||
613 | next_pageblock: | 617 | next_pageblock: |
614 | low_pfn += pageblock_nr_pages; | 618 | low_pfn = ALIGN(low_pfn + 1, pageblock_nr_pages) - 1; |
615 | low_pfn = ALIGN(low_pfn, pageblock_nr_pages) - 1; | ||
616 | last_pageblock_nr = pageblock_nr; | 619 | last_pageblock_nr = pageblock_nr; |
617 | } | 620 | } |
618 | 621 | ||
@@ -644,7 +647,7 @@ static void isolate_freepages(struct zone *zone, | |||
644 | struct compact_control *cc) | 647 | struct compact_control *cc) |
645 | { | 648 | { |
646 | struct page *page; | 649 | struct page *page; |
647 | unsigned long high_pfn, low_pfn, pfn, zone_end_pfn, end_pfn; | 650 | unsigned long high_pfn, low_pfn, pfn, z_end_pfn, end_pfn; |
648 | int nr_freepages = cc->nr_freepages; | 651 | int nr_freepages = cc->nr_freepages; |
649 | struct list_head *freelist = &cc->freepages; | 652 | struct list_head *freelist = &cc->freepages; |
650 | 653 | ||
@@ -663,7 +666,7 @@ static void isolate_freepages(struct zone *zone, | |||
663 | */ | 666 | */ |
664 | high_pfn = min(low_pfn, pfn); | 667 | high_pfn = min(low_pfn, pfn); |
665 | 668 | ||
666 | zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages; | 669 | z_end_pfn = zone_end_pfn(zone); |
667 | 670 | ||
668 | /* | 671 | /* |
669 | * Isolate free pages until enough are available to migrate the | 672 | * Isolate free pages until enough are available to migrate the |
@@ -706,7 +709,7 @@ static void isolate_freepages(struct zone *zone, | |||
706 | * only scans within a pageblock | 709 | * only scans within a pageblock |
707 | */ | 710 | */ |
708 | end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); | 711 | end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); |
709 | end_pfn = min(end_pfn, zone_end_pfn); | 712 | end_pfn = min(end_pfn, z_end_pfn); |
710 | isolated = isolate_freepages_block(cc, pfn, end_pfn, | 713 | isolated = isolate_freepages_block(cc, pfn, end_pfn, |
711 | freelist, false); | 714 | freelist, false); |
712 | nr_freepages += isolated; | 715 | nr_freepages += isolated; |
@@ -795,7 +798,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, | |||
795 | low_pfn = max(cc->migrate_pfn, zone->zone_start_pfn); | 798 | low_pfn = max(cc->migrate_pfn, zone->zone_start_pfn); |
796 | 799 | ||
797 | /* Only scan within a pageblock boundary */ | 800 | /* Only scan within a pageblock boundary */ |
798 | end_pfn = ALIGN(low_pfn + pageblock_nr_pages, pageblock_nr_pages); | 801 | end_pfn = ALIGN(low_pfn + 1, pageblock_nr_pages); |
799 | 802 | ||
800 | /* Do not cross the free scanner or scan within a memory hole */ | 803 | /* Do not cross the free scanner or scan within a memory hole */ |
801 | if (end_pfn > cc->free_pfn || !pfn_valid(low_pfn)) { | 804 | if (end_pfn > cc->free_pfn || !pfn_valid(low_pfn)) { |
@@ -920,7 +923,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) | |||
920 | { | 923 | { |
921 | int ret; | 924 | int ret; |
922 | unsigned long start_pfn = zone->zone_start_pfn; | 925 | unsigned long start_pfn = zone->zone_start_pfn; |
923 | unsigned long end_pfn = zone->zone_start_pfn + zone->spanned_pages; | 926 | unsigned long end_pfn = zone_end_pfn(zone); |
924 | 927 | ||
925 | ret = compaction_suitable(zone, cc->order); | 928 | ret = compaction_suitable(zone, cc->order); |
926 | switch (ret) { | 929 | switch (ret) { |
@@ -977,7 +980,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) | |||
977 | 980 | ||
978 | nr_migrate = cc->nr_migratepages; | 981 | nr_migrate = cc->nr_migratepages; |
979 | err = migrate_pages(&cc->migratepages, compaction_alloc, | 982 | err = migrate_pages(&cc->migratepages, compaction_alloc, |
980 | (unsigned long)cc, false, | 983 | (unsigned long)cc, |
981 | cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC, | 984 | cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC, |
982 | MR_COMPACTION); | 985 | MR_COMPACTION); |
983 | update_nr_listpages(cc); | 986 | update_nr_listpages(cc); |
@@ -1086,7 +1089,7 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, | |||
1086 | 1089 | ||
1087 | 1090 | ||
1088 | /* Compact all zones within a node */ | 1091 | /* Compact all zones within a node */ |
1089 | static int __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc) | 1092 | static void __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc) |
1090 | { | 1093 | { |
1091 | int zoneid; | 1094 | int zoneid; |
1092 | struct zone *zone; | 1095 | struct zone *zone; |
@@ -1119,28 +1122,26 @@ static int __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc) | |||
1119 | VM_BUG_ON(!list_empty(&cc->freepages)); | 1122 | VM_BUG_ON(!list_empty(&cc->freepages)); |
1120 | VM_BUG_ON(!list_empty(&cc->migratepages)); | 1123 | VM_BUG_ON(!list_empty(&cc->migratepages)); |
1121 | } | 1124 | } |
1122 | |||
1123 | return 0; | ||
1124 | } | 1125 | } |
1125 | 1126 | ||
1126 | int compact_pgdat(pg_data_t *pgdat, int order) | 1127 | void compact_pgdat(pg_data_t *pgdat, int order) |
1127 | { | 1128 | { |
1128 | struct compact_control cc = { | 1129 | struct compact_control cc = { |
1129 | .order = order, | 1130 | .order = order, |
1130 | .sync = false, | 1131 | .sync = false, |
1131 | }; | 1132 | }; |
1132 | 1133 | ||
1133 | return __compact_pgdat(pgdat, &cc); | 1134 | __compact_pgdat(pgdat, &cc); |
1134 | } | 1135 | } |
1135 | 1136 | ||
1136 | static int compact_node(int nid) | 1137 | static void compact_node(int nid) |
1137 | { | 1138 | { |
1138 | struct compact_control cc = { | 1139 | struct compact_control cc = { |
1139 | .order = -1, | 1140 | .order = -1, |
1140 | .sync = true, | 1141 | .sync = true, |
1141 | }; | 1142 | }; |
1142 | 1143 | ||
1143 | return __compact_pgdat(NODE_DATA(nid), &cc); | 1144 | __compact_pgdat(NODE_DATA(nid), &cc); |
1144 | } | 1145 | } |
1145 | 1146 | ||
1146 | /* Compact all nodes in the system */ | 1147 | /* Compact all nodes in the system */ |