aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/mmzone.h2
-rw-r--r--mm/compaction.c8
-rw-r--r--mm/internal.h2
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/vmscan.c4
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. */
223typedef unsigned __bitwise__ isolate_mode_t; 225typedef 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 */
477unsigned long 478unsigned long
478isolate_migratepages_range(struct zone *zone, struct compact_control *cc, 479isolate_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);
139unsigned long 139unsigned long
140isolate_migratepages_range(struct zone *zone, struct compact_control *cc, 140isolate_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;