From: Andi Kleen Date: Fri, 22 Oct 2010 15:40:48 +0000 (+0200) Subject: Merge branch 'hwpoison-hugepages' into hwpoison X-Git-Tag: v2.6.37-rc1~109^2 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=46e387bbd82d438b9131e237e6e2cb55a825da49;p=linux-pvops.git Merge branch 'hwpoison-hugepages' into hwpoison Conflicts: mm/memory-failure.c --- 46e387bbd82d438b9131e237e6e2cb55a825da49 diff --cc mm/memory-failure.c index 2044fe8920c2,14589a228e97..44a8cefeae6e --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@@ -1145,9 -1175,19 +1166,19 @@@ int unpoison_memory(unsigned long pfn nr_pages = 1 << compound_order(page); if (!get_page_unless_zero(page)) { + /* + * Since HWPoisoned hugepage should have non-zero refcount, + * race between memory failure and unpoison seems to happen. + * In such case unpoison fails and memory failure runs + * to the end. + */ + if (PageHuge(page)) { + pr_debug("MCE: Memory failure is now running on free hugepage %#lx\n", pfn); + return 0; + } if (TestClearPageHWPoison(p)) atomic_long_sub(nr_pages, &mce_bad_pages); - pr_debug("MCE: Software-unpoisoned free page %#lx\n", pfn); + pr_info("MCE: Software-unpoisoned free page %#lx\n", pfn); return 0; } @@@ -1159,12 -1199,12 +1190,12 @@@ * the free buddy page pool. */ if (TestClearPageHWPoison(page)) { - pr_debug("MCE: Software-unpoisoned page %#lx\n", pfn); + pr_info("MCE: Software-unpoisoned page %#lx\n", pfn); atomic_long_sub(nr_pages, &mce_bad_pages); freeit = 1; + if (PageHuge(page)) + clear_page_hwpoison_huge_page(page); } - if (PageHuge(p)) - clear_page_hwpoison_huge_page(page); unlock_page(page); put_page(page); @@@ -1206,9 -1250,16 +1241,16 @@@ static int get_any_page(struct page *p * was free. */ set_migratetype_isolate(p); + /* + * When the target page is a free hugepage, just remove it + * from free hugepage list. + */ if (!get_page_unless_zero(compound_head(p))) { - if (is_free_buddy_page(p)) { + if (PageHuge(p)) { - pr_debug("get_any_page: %#lx free huge page\n", pfn); ++ pr_info("get_any_page: %#lx free huge page\n", pfn); + ret = dequeue_hwpoisoned_huge_page(compound_head(p)); + } else if (is_free_buddy_page(p)) { - pr_debug("get_any_page: %#lx free buddy page\n", pfn); + pr_info("get_any_page: %#lx free buddy page\n", pfn); /* Set hwpoison bit while page is still isolated */ SetPageHWPoison(p); ret = 0;