diff options
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2015-08-06 15:46:58 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-08-07 04:39:41 +0300
commita09233f3e1b77dbf50851660533e008056553a2a (patch)
parente1832f2923ec92d0e590e496c8890675457f8568 (diff)
mm/memory-failure: unlock_page before put_page
Recently I addressed a few of hwpoison race problems and the patches are merged on v4.2-rc1. It made progress, but unfortunately some problems still remain due to less coverage of my testing. So I'm trying to fix or avoid them in this series. One point I'm expecting to discuss is that patch 4/5 changes the page flag set to be checked on free time. In current behavior, __PG_HWPOISON is not supposed to be set when the page is freed. I think that there is no strong reason for this behavior, and it causes a problem hard to fix only in error handler side (because __PG_HWPOISON could be set at arbitrary timing.) So I suggest to change it. With this patchset, hwpoison stress testing in official mce-test testsuite (which previously failed) passes. This patch (of 5): In "just unpoisoned" path, we do put_page and then unlock_page, which is a wrong order and causes "freeing locked page" bug. So let's fix it. Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Dean Nelson <dnelson@redhat.com> Cc: Tony Luck <tony.luck@intel.com> Cc: "Kirill A. Shutemov" <kirill@shutemov.name> Cc: Hugh Dickins <hughd@google.com> Acked-by: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 files changed, 2 insertions, 2 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index c53543d89282..04d677048af7 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1209,9 +1209,9 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
if (!PageHWPoison(p)) {
printk(KERN_ERR "MCE %#lx: just unpoisoned\n", pfn);
atomic_long_sub(nr_pages, &num_poisoned_pages);
+ unlock_page(hpage);
- res = 0;
- goto out;
+ return 0;
if (hwpoison_filter(p)) {
if (TestClearPageHWPoison(p))