aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorMinchan Kim <minchan@kernel.org>2012-07-31 19:43:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:42:45 -0400
commitee6f509c3274014d1f52e7a7a10aee9f85393c5e (patch)
treed8e5c816de0752b70b63f5de50ed52808ef3be9f /mm/page_alloc.c
parent876aafbfd9ba5bb352f1b14622c27f3fe9a99013 (diff)
mm: factor out memory isolate functions
mm/page_alloc.c has some memory isolation functions but they are used only when we enable CONFIG_{CMA|MEMORY_HOTPLUG|MEMORY_FAILURE}. So let's make it configurable by new CONFIG_MEMORY_ISOLATION so that it can reduce binary size and we can check it simple by CONFIG_MEMORY_ISOLATION, not if defined CONFIG_{CMA|MEMORY_HOTPLUG|MEMORY_FAILURE}. Signed-off-by: Minchan Kim <minchan@kernel.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Michal Hocko <mhocko@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c80
1 files changed, 4 insertions, 76 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 667338e80e94..228194728ccd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -51,7 +51,6 @@
51#include <linux/page_cgroup.h> 51#include <linux/page_cgroup.h>
52#include <linux/debugobjects.h> 52#include <linux/debugobjects.h>
53#include <linux/kmemleak.h> 53#include <linux/kmemleak.h>
54#include <linux/memory.h>
55#include <linux/compaction.h> 54#include <linux/compaction.h>
56#include <trace/events/kmem.h> 55#include <trace/events/kmem.h>
57#include <linux/ftrace_event.h> 56#include <linux/ftrace_event.h>
@@ -219,7 +218,7 @@ EXPORT_SYMBOL(nr_online_nodes);
219 218
220int page_group_by_mobility_disabled __read_mostly; 219int page_group_by_mobility_disabled __read_mostly;
221 220
222static void set_pageblock_migratetype(struct page *page, int migratetype) 221void set_pageblock_migratetype(struct page *page, int migratetype)
223{ 222{
224 223
225 if (unlikely(page_group_by_mobility_disabled)) 224 if (unlikely(page_group_by_mobility_disabled))
@@ -954,7 +953,7 @@ static int move_freepages(struct zone *zone,
954 return pages_moved; 953 return pages_moved;
955} 954}
956 955
957static int move_freepages_block(struct zone *zone, struct page *page, 956int move_freepages_block(struct zone *zone, struct page *page,
958 int migratetype) 957 int migratetype)
959{ 958{
960 unsigned long start_pfn, end_pfn; 959 unsigned long start_pfn, end_pfn;
@@ -5463,8 +5462,7 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
5463 * MIGRATE_MOVABLE block might include unmovable pages. It means you can't 5462 * MIGRATE_MOVABLE block might include unmovable pages. It means you can't
5464 * expect this function should be exact. 5463 * expect this function should be exact.
5465 */ 5464 */
5466static bool 5465bool has_unmovable_pages(struct zone *zone, struct page *page, int count)
5467__has_unmovable_pages(struct zone *zone, struct page *page, int count)
5468{ 5466{
5469 unsigned long pfn, iter, found; 5467 unsigned long pfn, iter, found;
5470 int mt; 5468 int mt;
@@ -5541,77 +5539,7 @@ bool is_pageblock_removable_nolock(struct page *page)
5541 zone->zone_start_pfn + zone->spanned_pages <= pfn) 5539 zone->zone_start_pfn + zone->spanned_pages <= pfn)
5542 return false; 5540 return false;
5543 5541
5544 return !__has_unmovable_pages(zone, page, 0); 5542 return !has_unmovable_pages(zone, page, 0);
5545}
5546
5547int set_migratetype_isolate(struct page *page)
5548{
5549 struct zone *zone;
5550 unsigned long flags, pfn;
5551 struct memory_isolate_notify arg;
5552 int notifier_ret;
5553 int ret = -EBUSY;
5554
5555 zone = page_zone(page);
5556
5557 spin_lock_irqsave(&zone->lock, flags);
5558
5559 pfn = page_to_pfn(page);
5560 arg.start_pfn = pfn;
5561 arg.nr_pages = pageblock_nr_pages;
5562 arg.pages_found = 0;
5563
5564 /*
5565 * It may be possible to isolate a pageblock even if the
5566 * migratetype is not MIGRATE_MOVABLE. The memory isolation
5567 * notifier chain is used by balloon drivers to return the
5568 * number of pages in a range that are held by the balloon
5569 * driver to shrink memory. If all the pages are accounted for
5570 * by balloons, are free, or on the LRU, isolation can continue.
5571 * Later, for example, when memory hotplug notifier runs, these
5572 * pages reported as "can be isolated" should be isolated(freed)
5573 * by the balloon driver through the memory notifier chain.
5574 */
5575 notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg);
5576 notifier_ret = notifier_to_errno(notifier_ret);
5577 if (notifier_ret)
5578 goto out;
5579 /*
5580 * FIXME: Now, memory hotplug doesn't call shrink_slab() by itself.
5581 * We just check MOVABLE pages.
5582 */
5583 if (!__has_unmovable_pages(zone, page, arg.pages_found))
5584 ret = 0;
5585 /*
5586 * Unmovable means "not-on-lru" pages. If Unmovable pages are
5587 * larger than removable-by-driver pages reported by notifier,
5588 * we'll fail.
5589 */
5590
5591out:
5592 if (!ret) {
5593 set_pageblock_migratetype(page, MIGRATE_ISOLATE);
5594 move_freepages_block(zone, page, MIGRATE_ISOLATE);
5595 }
5596
5597 spin_unlock_irqrestore(&zone->lock, flags);
5598 if (!ret)
5599 drain_all_pages();
5600 return ret;
5601}
5602
5603void unset_migratetype_isolate(struct page *page, unsigned migratetype)
5604{
5605 struct zone *zone;
5606 unsigned long flags;
5607 zone = page_zone(page);
5608 spin_lock_irqsave(&zone->lock, flags);
5609 if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
5610 goto out;
5611 set_pageblock_migratetype(page, migratetype);
5612 move_freepages_block(zone, page, migratetype);
5613out:
5614 spin_unlock_irqrestore(&zone->lock, flags);
5615} 5543}
5616 5544
5617#ifdef CONFIG_CMA 5545#ifdef CONFIG_CMA