diff options
| -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, |
