aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory-failure.c
diff options
context:
space:
mode:
authorJin Dongming <jin.dongming@np.css.fujitsu.com>2011-02-01 18:52:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-02-02 19:03:19 -0500
commitefeda7a41e09efce506a68c3549b60b16dd7dedd (patch)
treeaac3a6e4b1635dd4652bac9e4c3a94ff3962fe2e /mm/memory-failure.c
parentb16957c643de958ef731c03e0b24c5537490f196 (diff)
thp: fix splitting of hwpoisoned hugepages
The poisoned THP is now split with split_huge_page() in collect_procs_anon(). If kmalloc() is failed in collect_procs(), split_huge_page() could not be called. And the work after split_huge_page() for collecting the processes using poisoned page will not be done, too. So the processes using the poisoned page could not be killed. The condition becomes worse when CONFIG_DEBUG_VM == "Y". Because the poisoned THP could not be split, system panic will be caused by VM_BUG_ON(PageTransHuge(page)) in try_to_unmap(). This patch does: 1. move split_huge_page() to the place before collect_procs(). This can be sure the failure of splitting THP is caused by itself. 2. when splitting THP is failed, stop the operations after it. This can avoid unexpected system panic or non sense works. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Jin Dongming <jin.dongming@np.css.fujitsu.com> Reviewed-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory-failure.c')
-rw-r--r--mm/memory-failure.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 237aaa488f4..1e9c30b241c 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -386,8 +386,6 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
386 struct task_struct *tsk; 386 struct task_struct *tsk;
387 struct anon_vma *av; 387 struct anon_vma *av;
388 388
389 if (!PageHuge(page) && unlikely(split_huge_page(page)))
390 return;
391 read_lock(&tasklist_lock); 389 read_lock(&tasklist_lock);
392 av = page_lock_anon_vma(page); 390 av = page_lock_anon_vma(page);
393 if (av == NULL) /* Not actually mapped anymore */ 391 if (av == NULL) /* Not actually mapped anymore */
@@ -896,6 +894,34 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
896 } 894 }
897 } 895 }
898 896
897 if (PageTransHuge(hpage)) {
898 /*
899 * Verify that this isn't a hugetlbfs head page, the check for
900 * PageAnon is just for avoid tripping a split_huge_page
901 * internal debug check, as split_huge_page refuses to deal with
902 * anything that isn't an anon page. PageAnon can't go away fro
903 * under us because we hold a refcount on the hpage, without a
904 * refcount on the hpage. split_huge_page can't be safely called
905 * in the first place, having a refcount on the tail isn't
906 * enough * to be safe.
907 */
908 if (!PageHuge(hpage) && PageAnon(hpage)) {
909 if (unlikely(split_huge_page(hpage))) {
910 /*
911 * FIXME: if splitting THP is failed, it is
912 * better to stop the following operation rather
913 * than causing panic by unmapping. System might
914 * survive if the page is freed later.
915 */
916 printk(KERN_INFO
917 "MCE %#lx: failed to split THP\n", pfn);
918
919 BUG_ON(!PageHWPoison(p));
920 return SWAP_FAIL;
921 }
922 }
923 }
924
899 /* 925 /*
900 * First collect all the processes that have the page 926 * First collect all the processes that have the page
901 * mapped in dirty form. This has to be done before try_to_unmap, 927 * mapped in dirty form. This has to be done before try_to_unmap,