diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory-failure.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 237aaa488f4e..1e9c30b241c3 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, |