mm/memory-failure.c: move refcount only in !MF_COUNT_INCREASED
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Mon, 10 Feb 2014 22:25:50 +0000 (14:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 22 Feb 2014 20:41:26 +0000 (12:41 -0800)
commit 8d547ff4ac5927245e0833ac18528f939da0ee0e upstream.

mce-test detected a test failure when injecting error to a thp tail
page.  This is because we take page refcount of the tail page in
madvise_hwpoison() while the fix in commit a3e0f9e47d5e
("mm/memory-failure.c: transfer page count from head page to tail page
after split thp") assumes that we always take refcount on the head page.

When a real memory error happens we take refcount on the head page where
memory_failure() is called without MF_COUNT_INCREASED set, so it seems
to me that testing memory error on thp tail page using madvise makes
little sense.

This patch cancels moving refcount in !MF_COUNT_INCREASED for valid
testing.

[akpm@linux-foundation.org: s/&&/&/]
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Wanpeng Li <liwanp@linux.vnet.ibm.com>
Cc: Chen Gong <gong.chen@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mm/memory-failure.c

index f2a591d87d00f9b87eeac252eedb186b573cb33a..e386beefc994a8c789e6ca35d5fb7e276946b39f 100644 (file)
@@ -943,8 +943,10 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
                         * to it. Similarly, page lock is shifted.
                         */
                        if (hpage != p) {
-                               put_page(hpage);
-                               get_page(p);
+                               if (!(flags & MF_COUNT_INCREASED)) {
+                                       put_page(hpage);
+                                       get_page(p);
+                               }
                                lock_page(p);
                                unlock_page(hpage);
                                *hpagep = p;