mm: hwpoison: fix thp split handling in memory_failure()
When memory_failure() runs on a thp tail page after pmd is split, we
trigger the following VM_BUG_ON_PAGE():
page:ffffd7cd819b0040 count:0 mapcount:0 mapping: (null) index:0x1
flags: 0x1fffc000400000(hwpoison)
page dumped because: VM_BUG_ON_PAGE(!page_count(p))
------------[ cut here ]------------
kernel BUG at /src/linux-dev/mm/memory-failure.c:1132!
memory_failure() passed refcount and page lock from tail page to head
page, which is not needed because we can pass any subpage to
split_huge_page().
Fixes: 61f5d698cc
("mm: re-enable THP")
Link: http://lkml.kernel.org/r/1477961577-7183-1-git-send-email-n-horiguchi@ah.jp.nec.com
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: <stable@vger.kernel.org> [4.5+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
dd111be691
commit
c3901e722b
|
@ -1112,10 +1112,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
|
|||
}
|
||||
|
||||
if (!PageHuge(p) && PageTransHuge(hpage)) {
|
||||
lock_page(hpage);
|
||||
if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) {
|
||||
unlock_page(hpage);
|
||||
if (!PageAnon(hpage))
|
||||
lock_page(p);
|
||||
if (!PageAnon(p) || unlikely(split_huge_page(p))) {
|
||||
unlock_page(p);
|
||||
if (!PageAnon(p))
|
||||
pr_err("Memory failure: %#lx: non anonymous thp\n",
|
||||
pfn);
|
||||
else
|
||||
|
@ -1126,9 +1126,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
|
|||
put_hwpoison_page(p);
|
||||
return -EBUSY;
|
||||
}
|
||||
unlock_page(hpage);
|
||||
get_hwpoison_page(p);
|
||||
put_hwpoison_page(hpage);
|
||||
unlock_page(p);
|
||||
VM_BUG_ON_PAGE(!page_count(p), p);
|
||||
hpage = compound_head(p);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue