aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/page_alloc.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 4e869657cb51..d79b92580561 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -48,6 +48,7 @@
48#include <linux/page_cgroup.h> 48#include <linux/page_cgroup.h>
49#include <linux/debugobjects.h> 49#include <linux/debugobjects.h>
50#include <linux/kmemleak.h> 50#include <linux/kmemleak.h>
51#include <linux/memory.h>
51#include <trace/events/kmem.h> 52#include <trace/events/kmem.h>
52 53
53#include <asm/tlbflush.h> 54#include <asm/tlbflush.h>
@@ -5008,23 +5009,65 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
5008int set_migratetype_isolate(struct page *page) 5009int set_migratetype_isolate(struct page *page)
5009{ 5010{
5010 struct zone *zone; 5011 struct zone *zone;
5011 unsigned long flags; 5012 struct page *curr_page;
5013 unsigned long flags, pfn, iter;
5014 unsigned long immobile = 0;
5015 struct memory_isolate_notify arg;
5016 int notifier_ret;
5012 int ret = -EBUSY; 5017 int ret = -EBUSY;
5013 int zone_idx; 5018 int zone_idx;
5014 5019
5015 zone = page_zone(page); 5020 zone = page_zone(page);
5016 zone_idx = zone_idx(zone); 5021 zone_idx = zone_idx(zone);
5022
5017 spin_lock_irqsave(&zone->lock, flags); 5023 spin_lock_irqsave(&zone->lock, flags);
5024 if (get_pageblock_migratetype(page) == MIGRATE_MOVABLE ||
5025 zone_idx == ZONE_MOVABLE) {
5026 ret = 0;
5027 goto out;
5028 }
5029
5030 pfn = page_to_pfn(page);
5031 arg.start_pfn = pfn;
5032 arg.nr_pages = pageblock_nr_pages;
5033 arg.pages_found = 0;
5034
5018 /* 5035 /*
5019 * In future, more migrate types will be able to be isolation target. 5036 * It may be possible to isolate a pageblock even if the
5037 * migratetype is not MIGRATE_MOVABLE. The memory isolation
5038 * notifier chain is used by balloon drivers to return the
5039 * number of pages in a range that are held by the balloon
5040 * driver to shrink memory. If all the pages are accounted for
5041 * by balloons, are free, or on the LRU, isolation can continue.
5042 * Later, for example, when memory hotplug notifier runs, these
5043 * pages reported as "can be isolated" should be isolated(freed)
5044 * by the balloon driver through the memory notifier chain.
5020 */ 5045 */
5021 if (get_pageblock_migratetype(page) != MIGRATE_MOVABLE && 5046 notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg);
5022 zone_idx != ZONE_MOVABLE) 5047 notifier_ret = notifier_to_errno(notifier_ret);
5048 if (notifier_ret || !arg.pages_found)
5023 goto out; 5049 goto out;
5024 set_pageblock_migratetype(page, MIGRATE_ISOLATE); 5050
5025 move_freepages_block(zone, page, MIGRATE_ISOLATE); 5051 for (iter = pfn; iter < (pfn + pageblock_nr_pages); iter++) {
5026 ret = 0; 5052 if (!pfn_valid_within(pfn))
5053 continue;
5054
5055 curr_page = pfn_to_page(iter);
5056 if (!page_count(curr_page) || PageLRU(curr_page))
5057 continue;
5058
5059 immobile++;
5060 }
5061
5062 if (arg.pages_found == immobile)
5063 ret = 0;
5064
5027out: 5065out:
5066 if (!ret) {
5067 set_pageblock_migratetype(page, MIGRATE_ISOLATE);
5068 move_freepages_block(zone, page, MIGRATE_ISOLATE);
5069 }
5070
5028 spin_unlock_irqrestore(&zone->lock, flags); 5071 spin_unlock_irqrestore(&zone->lock, flags);
5029 if (!ret) 5072 if (!ret)
5030 drain_all_pages(); 5073 drain_all_pages();