diff options
-rw-r--r-- | include/linux/mmzone.h | 2 | ||||
-rw-r--r-- | mm/compaction.c | 8 | ||||
-rw-r--r-- | mm/internal.h | 2 | ||||
-rw-r--r-- | mm/page_alloc.c | 2 | ||||
-rw-r--r-- | mm/vmscan.c | 4 |
5 files changed, 12 insertions, 6 deletions
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index a5578871d03..50aaca81f63 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -218,6 +218,8 @@ struct lruvec { | |||
218 | #define ISOLATE_UNMAPPED ((__force isolate_mode_t)0x2) | 218 | #define ISOLATE_UNMAPPED ((__force isolate_mode_t)0x2) |
219 | /* Isolate for asynchronous migration */ | 219 | /* Isolate for asynchronous migration */ |
220 | #define ISOLATE_ASYNC_MIGRATE ((__force isolate_mode_t)0x4) | 220 | #define ISOLATE_ASYNC_MIGRATE ((__force isolate_mode_t)0x4) |
221 | /* Isolate unevictable pages */ | ||
222 | #define ISOLATE_UNEVICTABLE ((__force isolate_mode_t)0x8) | ||
221 | 223 | ||
222 | /* LRU Isolation modes. */ | 224 | /* LRU Isolation modes. */ |
223 | typedef unsigned __bitwise__ isolate_mode_t; | 225 | typedef unsigned __bitwise__ isolate_mode_t; |
diff --git a/mm/compaction.c b/mm/compaction.c index d8187f9cabb..2c4ce17651d 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -461,6 +461,7 @@ static bool too_many_isolated(struct zone *zone) | |||
461 | * @cc: Compaction control structure. | 461 | * @cc: Compaction control structure. |
462 | * @low_pfn: The first PFN of the range. | 462 | * @low_pfn: The first PFN of the range. |
463 | * @end_pfn: The one-past-the-last PFN of the range. | 463 | * @end_pfn: The one-past-the-last PFN of the range. |
464 | * @unevictable: true if it allows to isolate unevictable pages | ||
464 | * | 465 | * |
465 | * Isolate all pages that can be migrated from the range specified by | 466 | * Isolate all pages that can be migrated from the range specified by |
466 | * [low_pfn, end_pfn). Returns zero if there is a fatal signal | 467 | * [low_pfn, end_pfn). Returns zero if there is a fatal signal |
@@ -476,7 +477,7 @@ static bool too_many_isolated(struct zone *zone) | |||
476 | */ | 477 | */ |
477 | unsigned long | 478 | unsigned long |
478 | isolate_migratepages_range(struct zone *zone, struct compact_control *cc, | 479 | isolate_migratepages_range(struct zone *zone, struct compact_control *cc, |
479 | unsigned long low_pfn, unsigned long end_pfn) | 480 | unsigned long low_pfn, unsigned long end_pfn, bool unevictable) |
480 | { | 481 | { |
481 | unsigned long last_pageblock_nr = 0, pageblock_nr; | 482 | unsigned long last_pageblock_nr = 0, pageblock_nr; |
482 | unsigned long nr_scanned = 0, nr_isolated = 0; | 483 | unsigned long nr_scanned = 0, nr_isolated = 0; |
@@ -602,6 +603,9 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, | |||
602 | if (!cc->sync) | 603 | if (!cc->sync) |
603 | mode |= ISOLATE_ASYNC_MIGRATE; | 604 | mode |= ISOLATE_ASYNC_MIGRATE; |
604 | 605 | ||
606 | if (unevictable) | ||
607 | mode |= ISOLATE_UNEVICTABLE; | ||
608 | |||
605 | lruvec = mem_cgroup_page_lruvec(page, zone); | 609 | lruvec = mem_cgroup_page_lruvec(page, zone); |
606 | 610 | ||
607 | /* Try isolate the page */ | 611 | /* Try isolate the page */ |
@@ -807,7 +811,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, | |||
807 | } | 811 | } |
808 | 812 | ||
809 | /* Perform the isolation */ | 813 | /* Perform the isolation */ |
810 | low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn); | 814 | low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn, false); |
811 | if (!low_pfn || cc->contended) | 815 | if (!low_pfn || cc->contended) |
812 | return ISOLATE_ABORT; | 816 | return ISOLATE_ABORT; |
813 | 817 | ||
diff --git a/mm/internal.h b/mm/internal.h index 4dc93e2fe69..f5f295fe11e 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -138,7 +138,7 @@ isolate_freepages_range(struct compact_control *cc, | |||
138 | unsigned long start_pfn, unsigned long end_pfn); | 138 | unsigned long start_pfn, unsigned long end_pfn); |
139 | unsigned long | 139 | unsigned long |
140 | isolate_migratepages_range(struct zone *zone, struct compact_control *cc, | 140 | isolate_migratepages_range(struct zone *zone, struct compact_control *cc, |
141 | unsigned long low_pfn, unsigned long end_pfn); | 141 | unsigned long low_pfn, unsigned long end_pfn, bool unevictable); |
142 | 142 | ||
143 | #endif | 143 | #endif |
144 | 144 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5485f0ef4ec..fd86c47de86 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -5690,7 +5690,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc, | |||
5690 | if (list_empty(&cc->migratepages)) { | 5690 | if (list_empty(&cc->migratepages)) { |
5691 | cc->nr_migratepages = 0; | 5691 | cc->nr_migratepages = 0; |
5692 | pfn = isolate_migratepages_range(cc->zone, cc, | 5692 | pfn = isolate_migratepages_range(cc->zone, cc, |
5693 | pfn, end); | 5693 | pfn, end, true); |
5694 | if (!pfn) { | 5694 | if (!pfn) { |
5695 | ret = -EINTR; | 5695 | ret = -EINTR; |
5696 | break; | 5696 | break; |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 8b627309dd4..2624edcfb42 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1009,8 +1009,8 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode) | |||
1009 | if (!PageLRU(page)) | 1009 | if (!PageLRU(page)) |
1010 | return ret; | 1010 | return ret; |
1011 | 1011 | ||
1012 | /* Do not give back unevictable pages for compaction */ | 1012 | /* Compaction should not handle unevictable pages but CMA can do so */ |
1013 | if (PageUnevictable(page)) | 1013 | if (PageUnevictable(page) && !(mode & ISOLATE_UNEVICTABLE)) |
1014 | return ret; | 1014 | return ret; |
1015 | 1015 | ||
1016 | ret = -EBUSY; | 1016 | ret = -EBUSY; |