Commit 626d06a2 authored by Miaohe Lin's avatar Miaohe Lin Committed by Yongqiang Liu
Browse files

mm/memory-failure.c: fix race with changing page more robustly

mainline inclusion
from mainline-v5.18-rc1
commit 75ee64b3
category: bugfix
bugzilla: 188200, https://gitee.com/openeuler/kernel/issues/I68OOI
CVE: NA

--------------------------------

We're only intended to deal with the non-Compound page after we split
thp in memory_failure.  However, the page could have changed compound
pages due to race window.  If this happens, we could retry once to
hopefully handle the page next round.  Also remove unneeded orig_head.
It's always equal to the hpage.  So we can use hpage directly and remove
this redundant one.

Link: https://lkml.kernel.org/r/20220218090118.1105-5-linmiaohe@huawei.com


Signed-off-by: default avatarMiaohe Lin <linmiaohe@huawei.com>
Acked-by: default avatarNaoya Horiguchi <naoya.horiguchi@nec.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarMa Wupeng <mawupeng1@huawei.com>
Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarYongqiang Liu <liuyongqiang13@huawei.com>
parent f0c2fbe9
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -1345,7 +1345,6 @@ int memory_failure(unsigned long pfn, int flags)
{
	struct page *p;
	struct page *hpage;
	struct page *orig_head;
	struct dev_pagemap *pgmap;
	int res = 0;
	unsigned long page_flags;
@@ -1383,7 +1382,7 @@ int memory_failure(unsigned long pfn, int flags)
		goto unlock_mutex;
	}

	orig_head = hpage = compound_head(p);
	hpage = compound_head(p);
	num_poisoned_pages_inc();

	/*
@@ -1443,10 +1442,21 @@ int memory_failure(unsigned long pfn, int flags)
	lock_page(p);

	/*
	 * The page could have changed compound pages during the locking.
	 * If this happens just bail out.
	 * We're only intended to deal with the non-Compound page here.
	 * However, the page could have changed compound pages due to
	 * race window. If this happens, we could try again to hopefully
	 * handle the page next round.
	 */
	if (PageCompound(p) && compound_head(p) != orig_head) {
	if (PageCompound(p)) {
		if (retry) {
			if (TestClearPageHWPoison(p))
				num_poisoned_pages_dec();
			unlock_page(p);
			put_page(p);
			flags &= ~MF_COUNT_INCREASED;
			retry = false;
			goto try_again;
		}
		action_result(pfn, MF_MSG_DIFFERENT_COMPOUND, MF_IGNORED);
		res = -EBUSY;
		goto unlock_page;