]>
Commit | Line | Data |
---|---|---|
885c8f02 GKH |
1 | From 31286a8484a85e8b4e91ddb0f5415aee8a416827 Mon Sep 17 00:00:00 2001 |
2 | From: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | |
3 | Date: Thu, 5 Apr 2018 16:23:05 -0700 | |
4 | Subject: mm: hwpoison: disable memory error handling on 1GB hugepage | |
5 | ||
6 | From: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | |
7 | ||
8 | commit 31286a8484a85e8b4e91ddb0f5415aee8a416827 upstream. | |
9 | ||
10 | Recently the following BUG was reported: | |
11 | ||
12 | Injecting memory failure for pfn 0x3c0000 at process virtual address 0x7fe300000000 | |
13 | Memory failure: 0x3c0000: recovery action for huge page: Recovered | |
14 | BUG: unable to handle kernel paging request at ffff8dfcc0003000 | |
15 | IP: gup_pgd_range+0x1f0/0xc20 | |
16 | PGD 17ae72067 P4D 17ae72067 PUD 0 | |
17 | Oops: 0000 [#1] SMP PTI | |
18 | ... | |
19 | CPU: 3 PID: 5467 Comm: hugetlb_1gb Not tainted 4.15.0-rc8-mm1-abc+ #3 | |
20 | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc25 04/01/2014 | |
21 | ||
22 | You can easily reproduce this by calling madvise(MADV_HWPOISON) twice on | |
23 | a 1GB hugepage. This happens because get_user_pages_fast() is not aware | |
24 | of a migration entry on pud that was created in the 1st madvise() event. | |
25 | ||
26 | I think that conversion to pud-aligned migration entry is working, but | |
27 | other MM code walking over page table isn't prepared for it. We need | |
28 | some time and effort to make all this work properly, so this patch | |
29 | avoids the reported bug by just disabling error handling for 1GB | |
30 | hugepage. | |
31 | ||
32 | [n-horiguchi@ah.jp.nec.com: v2] | |
33 | Link: http://lkml.kernel.org/r/1517284444-18149-1-git-send-email-n-horiguchi@ah.jp.nec.com | |
34 | Link: http://lkml.kernel.org/r/1517207283-15769-1-git-send-email-n-horiguchi@ah.jp.nec.com | |
35 | Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | |
36 | Acked-by: Michal Hocko <mhocko@suse.com> | |
37 | Reviewed-by: Andrew Morton <akpm@linux-foundation.org> | |
38 | Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com> | |
39 | Acked-by: Punit Agrawal <punit.agrawal@arm.com> | |
40 | Tested-by: Michael Ellerman <mpe@ellerman.id.au> | |
41 | Cc: Anshuman Khandual <khandual@linux.vnet.ibm.com> | |
42 | Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> | |
43 | Cc: <stable@vger.kernel.org> | |
44 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
45 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
46 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
47 | ||
48 | --- | |
49 | include/linux/mm.h | 1 + | |
50 | mm/memory-failure.c | 16 ++++++++++++++++ | |
51 | 2 files changed, 17 insertions(+) | |
52 | ||
53 | --- a/include/linux/mm.h | |
54 | +++ b/include/linux/mm.h | |
55 | @@ -2604,6 +2604,7 @@ enum mf_action_page_type { | |
56 | MF_MSG_POISONED_HUGE, | |
57 | MF_MSG_HUGE, | |
58 | MF_MSG_FREE_HUGE, | |
59 | + MF_MSG_NON_PMD_HUGE, | |
60 | MF_MSG_UNMAP_FAILED, | |
61 | MF_MSG_DIRTY_SWAPCACHE, | |
62 | MF_MSG_CLEAN_SWAPCACHE, | |
63 | --- a/mm/memory-failure.c | |
64 | +++ b/mm/memory-failure.c | |
65 | @@ -502,6 +502,7 @@ static const char * const action_page_ty | |
66 | [MF_MSG_POISONED_HUGE] = "huge page already hardware poisoned", | |
67 | [MF_MSG_HUGE] = "huge page", | |
68 | [MF_MSG_FREE_HUGE] = "free huge page", | |
69 | + [MF_MSG_NON_PMD_HUGE] = "non-pmd-sized huge page", | |
70 | [MF_MSG_UNMAP_FAILED] = "unmapping failed page", | |
71 | [MF_MSG_DIRTY_SWAPCACHE] = "dirty swapcache page", | |
72 | [MF_MSG_CLEAN_SWAPCACHE] = "clean swapcache page", | |
73 | @@ -1084,6 +1085,21 @@ static int memory_failure_hugetlb(unsign | |
74 | return 0; | |
75 | } | |
76 | ||
77 | + /* | |
78 | + * TODO: hwpoison for pud-sized hugetlb doesn't work right now, so | |
79 | + * simply disable it. In order to make it work properly, we need | |
80 | + * make sure that: | |
81 | + * - conversion of a pud that maps an error hugetlb into hwpoison | |
82 | + * entry properly works, and | |
83 | + * - other mm code walking over page table is aware of pud-aligned | |
84 | + * hwpoison entries. | |
85 | + */ | |
86 | + if (huge_page_size(page_hstate(head)) > PMD_SIZE) { | |
87 | + action_result(pfn, MF_MSG_NON_PMD_HUGE, MF_IGNORED); | |
88 | + res = -EBUSY; | |
89 | + goto out; | |
90 | + } | |
91 | + | |
92 | if (!hwpoison_user_mappings(p, pfn, flags, &head)) { | |
93 | action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED); | |
94 | res = -EBUSY; |