]>
Commit | Line | Data |
---|---|---|
d5b95bcd GKH |
1 | From 46612b751c4941c5c0472ddf04027e877ae5990f Mon Sep 17 00:00:00 2001 |
2 | From: zhongjiang <zhongjiang@huawei.com> | |
3 | Date: Tue, 5 Mar 2019 15:41:16 -0800 | |
4 | Subject: mm: hwpoison: fix thp split handing in soft_offline_in_use_page() | |
5 | ||
6 | From: zhongjiang <zhongjiang@huawei.com> | |
7 | ||
8 | commit 46612b751c4941c5c0472ddf04027e877ae5990f upstream. | |
9 | ||
10 | When soft_offline_in_use_page() runs on a thp tail page after pmd is | |
11 | split, we trigger the following VM_BUG_ON_PAGE(): | |
12 | ||
13 | Memory failure: 0x3755ff: non anonymous thp | |
14 | __get_any_page: 0x3755ff: unknown zero refcount page type 2fffff80000000 | |
15 | Soft offlining pfn 0x34d805 at process virtual address 0x20fff000 | |
16 | page:ffffea000d360140 count:0 mapcount:0 mapping:0000000000000000 index:0x1 | |
17 | flags: 0x2fffff80000000() | |
18 | raw: 002fffff80000000 ffffea000d360108 ffffea000d360188 0000000000000000 | |
19 | raw: 0000000000000001 0000000000000000 00000000ffffffff 0000000000000000 | |
20 | page dumped because: VM_BUG_ON_PAGE(page_ref_count(page) == 0) | |
21 | ------------[ cut here ]------------ | |
22 | kernel BUG at ./include/linux/mm.h:519! | |
23 | ||
24 | soft_offline_in_use_page() passed refcount and page lock from tail page | |
25 | to head page, which is not needed because we can pass any subpage to | |
26 | split_huge_page(). | |
27 | ||
28 | Naoya had fixed a similar issue in c3901e722b29 ("mm: hwpoison: fix thp | |
29 | split handling in memory_failure()"). But he missed fixing soft | |
30 | offline. | |
31 | ||
32 | Link: http://lkml.kernel.org/r/1551452476-24000-1-git-send-email-zhongjiang@huawei.com | |
33 | Fixes: 61f5d698cc97 ("mm: re-enable THP") | |
34 | Signed-off-by: zhongjiang <zhongjiang@huawei.com> | |
35 | Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | |
36 | Cc: Michal Hocko <mhocko@suse.com> | |
37 | Cc: Hugh Dickins <hughd@google.com> | |
38 | Cc: Kirill A. Shutemov <kirill@shutemov.name> | |
39 | Cc: Andrea Arcangeli <aarcange@redhat.com> | |
40 | Cc: <stable@vger.kernel.org> [4.5+] | |
41 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
42 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
43 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
44 | ||
45 | --- | |
46 | mm/memory-failure.c | 14 ++++++-------- | |
47 | 1 file changed, 6 insertions(+), 8 deletions(-) | |
48 | ||
49 | --- a/mm/memory-failure.c | |
50 | +++ b/mm/memory-failure.c | |
51 | @@ -1701,19 +1701,17 @@ static int soft_offline_in_use_page(stru | |
52 | struct page *hpage = compound_head(page); | |
53 | ||
54 | if (!PageHuge(page) && PageTransHuge(hpage)) { | |
55 | - lock_page(hpage); | |
56 | - if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) { | |
57 | - unlock_page(hpage); | |
58 | - if (!PageAnon(hpage)) | |
59 | + lock_page(page); | |
60 | + if (!PageAnon(page) || unlikely(split_huge_page(page))) { | |
61 | + unlock_page(page); | |
62 | + if (!PageAnon(page)) | |
63 | pr_info("soft offline: %#lx: non anonymous thp\n", page_to_pfn(page)); | |
64 | else | |
65 | pr_info("soft offline: %#lx: thp split failed\n", page_to_pfn(page)); | |
66 | - put_hwpoison_page(hpage); | |
67 | + put_hwpoison_page(page); | |
68 | return -EBUSY; | |
69 | } | |
70 | - unlock_page(hpage); | |
71 | - get_hwpoison_page(page); | |
72 | - put_hwpoison_page(hpage); | |
73 | + unlock_page(page); | |
74 | } | |
75 | ||
76 | if (PageHuge(page)) |