Skip to content

Commit 31286a8

Browse files
Naoya Horiguchitorvalds
Naoya Horiguchi
authored andcommitted
mm: hwpoison: disable memory error handling on 1GB hugepage
Recently the following BUG was reported: Injecting memory failure for pfn 0x3c0000 at process virtual address 0x7fe300000000 Memory failure: 0x3c0000: recovery action for huge page: Recovered BUG: unable to handle kernel paging request at ffff8dfcc0003000 IP: gup_pgd_range+0x1f0/0xc20 PGD 17ae72067 P4D 17ae72067 PUD 0 Oops: 0000 [#1] SMP PTI ... CPU: 3 PID: 5467 Comm: hugetlb_1gb Not tainted 4.15.0-rc8-mm1-abc+ #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.9.3-1.fc25 04/01/2014 You can easily reproduce this by calling madvise(MADV_HWPOISON) twice on a 1GB hugepage. This happens because get_user_pages_fast() is not aware of a migration entry on pud that was created in the 1st madvise() event. I think that conversion to pud-aligned migration entry is working, but other MM code walking over page table isn't prepared for it. We need some time and effort to make all this work properly, so this patch avoids the reported bug by just disabling error handling for 1GB hugepage. [[email protected]: v2] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Naoya Horiguchi <[email protected]> Acked-by: Michal Hocko <[email protected]> Reviewed-by: Andrew Morton <[email protected]> Reviewed-by: Mike Kravetz <[email protected]> Acked-by: Punit Agrawal <[email protected]> Tested-by: Michael Ellerman <[email protected]> Cc: Anshuman Khandual <[email protected]> Cc: "Aneesh Kumar K.V" <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent d0dc12e commit 31286a8

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

include/linux/mm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,6 +2613,7 @@ enum mf_action_page_type {
26132613
MF_MSG_POISONED_HUGE,
26142614
MF_MSG_HUGE,
26152615
MF_MSG_FREE_HUGE,
2616+
MF_MSG_NON_PMD_HUGE,
26162617
MF_MSG_UNMAP_FAILED,
26172618
MF_MSG_DIRTY_SWAPCACHE,
26182619
MF_MSG_CLEAN_SWAPCACHE,

mm/memory-failure.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ static const char * const action_page_types[] = {
502502
[MF_MSG_POISONED_HUGE] = "huge page already hardware poisoned",
503503
[MF_MSG_HUGE] = "huge page",
504504
[MF_MSG_FREE_HUGE] = "free huge page",
505+
[MF_MSG_NON_PMD_HUGE] = "non-pmd-sized huge page",
505506
[MF_MSG_UNMAP_FAILED] = "unmapping failed page",
506507
[MF_MSG_DIRTY_SWAPCACHE] = "dirty swapcache page",
507508
[MF_MSG_CLEAN_SWAPCACHE] = "clean swapcache page",
@@ -1084,6 +1085,21 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
10841085
return 0;
10851086
}
10861087

1088+
/*
1089+
* TODO: hwpoison for pud-sized hugetlb doesn't work right now, so
1090+
* simply disable it. In order to make it work properly, we need
1091+
* make sure that:
1092+
* - conversion of a pud that maps an error hugetlb into hwpoison
1093+
* entry properly works, and
1094+
* - other mm code walking over page table is aware of pud-aligned
1095+
* hwpoison entries.
1096+
*/
1097+
if (huge_page_size(page_hstate(head)) > PMD_SIZE) {
1098+
action_result(pfn, MF_MSG_NON_PMD_HUGE, MF_IGNORED);
1099+
res = -EBUSY;
1100+
goto out;
1101+
}
1102+
10871103
if (!hwpoison_user_mappings(p, pfn, flags, &head)) {
10881104
action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED);
10891105
res = -EBUSY;

0 commit comments

Comments
 (0)