diff options
author | Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | 2015-08-06 18:47:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-08-06 21:39:42 -0400 |
commit | 4491f7126063ef51081f5662bd4fcae31621a333 (patch) | |
tree | 0ebbdbf7d1eec49ec3727876524a95e48f317727 | |
parent | f4c18e6f7b5bbb5b528b3334115806b0d76f50f9 (diff) |
mm/memory-failure: set PageHWPoison before migrate_pages()
Now page freeing code doesn't consider PageHWPoison as a bad page, so by
setting it before completing the page containment, we can prevent the
error page from being reused just after successful page migration.
I added TTU_IGNORE_HWPOISON for try_to_unmap() to make sure that the
page table entry is transformed into migration entry, not to hwpoison
entry.
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Dean Nelson <dnelson@redhat.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Hugh Dickins <hughd@google.com>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/memory-failure.c | 7 | ||||
-rw-r--r-- | mm/migrate.c | 3 |
2 files changed, 6 insertions, 4 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index cd985530f102..ea5a93659488 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -1659,6 +1659,8 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1659 | inc_zone_page_state(page, NR_ISOLATED_ANON + | 1659 | inc_zone_page_state(page, NR_ISOLATED_ANON + |
1660 | page_is_file_cache(page)); | 1660 | page_is_file_cache(page)); |
1661 | list_add(&page->lru, &pagelist); | 1661 | list_add(&page->lru, &pagelist); |
1662 | if (!TestSetPageHWPoison(page)) | ||
1663 | atomic_long_inc(&num_poisoned_pages); | ||
1662 | ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, | 1664 | ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, |
1663 | MIGRATE_SYNC, MR_MEMORY_FAILURE); | 1665 | MIGRATE_SYNC, MR_MEMORY_FAILURE); |
1664 | if (ret) { | 1666 | if (ret) { |
@@ -1673,9 +1675,8 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1673 | pfn, ret, page->flags); | 1675 | pfn, ret, page->flags); |
1674 | if (ret > 0) | 1676 | if (ret > 0) |
1675 | ret = -EIO; | 1677 | ret = -EIO; |
1676 | } else { | 1678 | if (TestClearPageHWPoison(page)) |
1677 | if (!TestSetPageHWPoison(page)) | 1679 | atomic_long_dec(&num_poisoned_pages); |
1678 | atomic_long_inc(&num_poisoned_pages); | ||
1679 | } | 1680 | } |
1680 | } else { | 1681 | } else { |
1681 | pr_info("soft offline: %#lx: isolation failed: %d, page count %d, type %lx\n", | 1682 | pr_info("soft offline: %#lx: isolation failed: %d, page count %d, type %lx\n", |
diff --git a/mm/migrate.c b/mm/migrate.c index f2415be7d93b..eb4267107d1f 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -880,7 +880,8 @@ static int __unmap_and_move(struct page *page, struct page *newpage, | |||
880 | /* Establish migration ptes or remove ptes */ | 880 | /* Establish migration ptes or remove ptes */ |
881 | if (page_mapped(page)) { | 881 | if (page_mapped(page)) { |
882 | try_to_unmap(page, | 882 | try_to_unmap(page, |
883 | TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS); | 883 | TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS| |
884 | TTU_IGNORE_HWPOISON); | ||
884 | page_was_mapped = 1; | 885 | page_was_mapped = 1; |
885 | } | 886 | } |
886 | 887 | ||