aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorWen Congyang <wency@cn.fujitsu.com>2012-12-11 19:00:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 20:22:22 -0500
commitb023f46813cde6e3b8a8c24f432ff9c1fd8e9a64 (patch)
treeedac3509e7c44136450e20d7f9cc81de35926650 /mm/page_alloc.c
parentfa7194eb99b8e9fefe96f045002648ffb55f53c0 (diff)
memory-hotplug: skip HWPoisoned page when offlining pages
hwpoisoned may be set when we offline a page by the sysfs interface /sys/devices/system/memory/soft_offline_page or /sys/devices/system/memory/hard_offline_page. If we don't clear this flag when onlining pages, this page can't be freed, and will not in free list. So we can't offline these pages again. So we should skip such page when offlining pages. Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Cc: David Rientjes <rientjes@google.com> Cc: Jiang Liu <liuj97@gmail.com> Cc: Len Brown <len.brown@intel.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Christoph Lameter <cl@linux.com> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Mel Gorman <mel@csn.ul.ie> 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.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a49b0ea3cc2f..6f50cfe98a7b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5616,7 +5616,8 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags,
5616 * MIGRATE_MOVABLE block might include unmovable pages. It means you can't 5616 * MIGRATE_MOVABLE block might include unmovable pages. It means you can't
5617 * expect this function should be exact. 5617 * expect this function should be exact.
5618 */ 5618 */
5619bool has_unmovable_pages(struct zone *zone, struct page *page, int count) 5619bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
5620 bool skip_hwpoisoned_pages)
5620{ 5621{
5621 unsigned long pfn, iter, found; 5622 unsigned long pfn, iter, found;
5622 int mt; 5623 int mt;
@@ -5651,6 +5652,13 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count)
5651 continue; 5652 continue;
5652 } 5653 }
5653 5654
5655 /*
5656 * The HWPoisoned page may be not in buddy system, and
5657 * page_count() is not 0.
5658 */
5659 if (skip_hwpoisoned_pages && PageHWPoison(page))
5660 continue;
5661
5654 if (!PageLRU(page)) 5662 if (!PageLRU(page))
5655 found++; 5663 found++;
5656 /* 5664 /*
@@ -5693,7 +5701,7 @@ bool is_pageblock_removable_nolock(struct page *page)
5693 zone->zone_start_pfn + zone->spanned_pages <= pfn) 5701 zone->zone_start_pfn + zone->spanned_pages <= pfn)
5694 return false; 5702 return false;
5695 5703
5696 return !has_unmovable_pages(zone, page, 0); 5704 return !has_unmovable_pages(zone, page, 0, true);
5697} 5705}
5698 5706
5699#ifdef CONFIG_CMA 5707#ifdef CONFIG_CMA
@@ -5864,7 +5872,8 @@ int alloc_contig_range(unsigned long start, unsigned long end,
5864 */ 5872 */
5865 5873
5866 ret = start_isolate_page_range(pfn_max_align_down(start), 5874 ret = start_isolate_page_range(pfn_max_align_down(start),
5867 pfn_max_align_up(end), migratetype); 5875 pfn_max_align_up(end), migratetype,
5876 false);
5868 if (ret) 5877 if (ret)
5869 return ret; 5878 return ret;
5870 5879
@@ -5903,7 +5912,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
5903 } 5912 }
5904 5913
5905 /* Make sure the range is really isolated. */ 5914 /* Make sure the range is really isolated. */
5906 if (test_pages_isolated(outer_start, end)) { 5915 if (test_pages_isolated(outer_start, end, false)) {
5907 pr_warn("alloc_contig_range test_pages_isolated(%lx, %lx) failed\n", 5916 pr_warn("alloc_contig_range test_pages_isolated(%lx, %lx) failed\n",
5908 outer_start, end); 5917 outer_start, end);
5909 ret = -EBUSY; 5918 ret = -EBUSY;
@@ -6018,6 +6027,16 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
6018 continue; 6027 continue;
6019 } 6028 }
6020 page = pfn_to_page(pfn); 6029 page = pfn_to_page(pfn);
6030 /*
6031 * The HWPoisoned page may be not in buddy system, and
6032 * page_count() is not 0.
6033 */
6034 if (unlikely(!PageBuddy(page) && PageHWPoison(page))) {
6035 pfn++;
6036 SetPageReserved(page);
6037 continue;
6038 }
6039
6021 BUG_ON(page_count(page)); 6040 BUG_ON(page_count(page));
6022 BUG_ON(!PageBuddy(page)); 6041 BUG_ON(!PageBuddy(page));
6023 order = page_order(page); 6042 order = page_order(page);