aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2016-11-10 13:46:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-11-11 11:12:37 -0500
commitc3901e722b2975666f42748340df798114742d6d (patch)
tree9cd4508bd975e35b393982f3c61101c98c90dee6
parentdd111be69114cc867f8e826284559bfbc1c40e37 (diff)
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: 61f5d698cc97 ("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>
-rw-r--r--mm/memory-failure.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index de88f33519c0..19e796d36a62 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1112,10 +1112,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1112 } 1112 }
1113 1113
1114 if (!PageHuge(p) && PageTransHuge(hpage)) { 1114 if (!PageHuge(p) && PageTransHuge(hpage)) {
1115 lock_page(hpage); 1115 lock_page(p);
1116 if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) { 1116 if (!PageAnon(p) || unlikely(split_huge_page(p))) {
1117 unlock_page(hpage); 1117 unlock_page(p);
1118 if (!PageAnon(hpage)) 1118 if (!PageAnon(p))
1119 pr_err("Memory failure: %#lx: non anonymous thp\n", 1119 pr_err("Memory failure: %#lx: non anonymous thp\n",
1120 pfn); 1120 pfn);
1121 else 1121 else
@@ -1126,9 +1126,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1126 put_hwpoison_page(p); 1126 put_hwpoison_page(p);
1127 return -EBUSY; 1127 return -EBUSY;
1128 } 1128 }
1129 unlock_page(hpage); 1129 unlock_page(p);
1130 get_hwpoison_page(p);
1131 put_hwpoison_page(hpage);
1132 VM_BUG_ON_PAGE(!page_count(p), p); 1130 VM_BUG_ON_PAGE(!page_count(p), p);
1133 hpage = compound_head(p); 1131 hpage = compound_head(p);
1134 } 1132 }