aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2014-08-06 19:06:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 21:01:19 -0400
commitf37d4298aa7f8b74395aa13c728677e2ed86fdaf (patch)
treeddbf92044a7e44a2840ba2a4f985123dfadfd410
parentad4404a226ea92f2966f0e5378614e15ff4a7c76 (diff)
hwpoison: fix race with changing page during offlining
When a hwpoison page is locked it could change state due to parallel modifications. The original compound page can be torn down and then this 4k page becomes part of a differently-size compound page is is a standalone regular page. Check after the lock if the page is still the same compound page. We could go back, grab the new head page and try again but it should be quite rare, so I thought this was safest. A retry loop would be more difficult to test and may have more side effects. The hwpoison code by design only tries to handle cases that are reasonably common in workloads, as visible in page-flags. I'm not really that concerned about handling this (likely rare case), just not crashing on it. Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/memory-failure.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index a013bc94ebbe..44c6bd201d3a 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1173,6 +1173,16 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
1173 lock_page(hpage); 1173 lock_page(hpage);
1174 1174
1175 /* 1175 /*
1176 * The page could have changed compound pages during the locking.
1177 * If this happens just bail out.
1178 */
1179 if (compound_head(p) != hpage) {
1180 action_result(pfn, "different compound page after locking", IGNORED);
1181 res = -EBUSY;
1182 goto out;
1183 }
1184
1185 /*
1176 * We use page flags to determine what action should be taken, but 1186 * We use page flags to determine what action should be taken, but
1177 * the flags can be modified by the error containment action. One 1187 * the flags can be modified by the error containment action. One
1178 * example is an mlocked page, where PG_mlocked is cleared by 1188 * example is an mlocked page, where PG_mlocked is cleared by