diff options
author | Minchan Kim <minchan@kernel.org> | 2012-07-31 19:43:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:42:45 -0400 |
commit | ee6f509c3274014d1f52e7a7a10aee9f85393c5e (patch) | |
tree | d8e5c816de0752b70b63f5de50ed52808ef3be9f /mm/page_alloc.c | |
parent | 876aafbfd9ba5bb352f1b14622c27f3fe9a99013 (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.c | 80 |
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 | ||
220 | int page_group_by_mobility_disabled __read_mostly; | 219 | int page_group_by_mobility_disabled __read_mostly; |
221 | 220 | ||
222 | static void set_pageblock_migratetype(struct page *page, int migratetype) | 221 | void 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 | ||
957 | static int move_freepages_block(struct zone *zone, struct page *page, | 956 | int 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 | */ |
5466 | static bool | 5465 | bool 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 | |||
5547 | int 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 | |||
5591 | out: | ||
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 | |||
5603 | void 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); | ||
5613 | out: | ||
5614 | spin_unlock_irqrestore(&zone->lock, flags); | ||
5615 | } | 5543 | } |
5616 | 5544 | ||
5617 | #ifdef CONFIG_CMA | 5545 | #ifdef CONFIG_CMA |