summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorMiaohe Lin <linmiaohe@huawei.com>2022-03-22 14:44:44 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-07-12 16:35:05 +0200
commit5429eb5502fc7e64abdb3a4f6b9f698a8337da5d (patch)
treee046a81252e81847d90c86b976f9f75a5f4ab289 /mm
parent7a07875fabccc17c4564151c19de2174948d0544 (diff)
downloadlinux-5429eb5502fc7e64abdb3a4f6b9f698a8337da5d.tar.gz
linux-5429eb5502fc7e64abdb3a4f6b9f698a8337da5d.tar.bz2
linux-5429eb5502fc7e64abdb3a4f6b9f698a8337da5d.zip
mm/memory-failure.c: fix race with changing page compound again
[ Upstream commit 888af2701db79b9b27c7e37f9ede528a5ca53b76 ] Patch series "A few fixup patches for memory failure", v2. This series contains a few patches to fix the race with changing page compound page, make non-LRU movable pages unhandlable and so on. More details can be found in the respective changelogs. There is a race window where we got the compound_head, the hugetlb page could be freed to buddy, or even changed to another compound page just before we try to get hwpoison page. Think about the below race window: CPU 1 CPU 2 memory_failure_hugetlb struct page *head = compound_head(p); hugetlb page might be freed to buddy, or even changed to another compound page. get_hwpoison_page -- page is not what we want now... If this race happens, just bail out. Also MF_MSG_DIFFERENT_PAGE_SIZE is introduced to record this event. [akpm@linux-foundation.org: s@/**@/*@, per Naoya Horiguchi] Link: https://lkml.kernel.org/r/20220312074613.4798-1-linmiaohe@huawei.com Link: https://lkml.kernel.org/r/20220312074613.4798-2-linmiaohe@huawei.com Signed-off-by: Miaohe Lin <linmiaohe@huawei.com> Acked-by: Naoya Horiguchi <naoya.horiguchi@nec.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Yang Shi <shy828301@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memory-failure.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 5664bafd5e77..a4d70c21c146 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -741,6 +741,7 @@ static const char * const action_page_types[] = {
[MF_MSG_BUDDY_2ND] = "free buddy page (2nd try)",
[MF_MSG_DAX] = "dax page",
[MF_MSG_UNSPLIT_THP] = "unsplit thp",
+ [MF_MSG_DIFFERENT_PAGE_SIZE] = "different page size",
[MF_MSG_UNKNOWN] = "unknown page",
};
@@ -1461,6 +1462,17 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
}
lock_page(head);
+
+ /*
+ * The page could have changed compound pages due to race window.
+ * If this happens just bail out.
+ */
+ if (!PageHuge(p) || compound_head(p) != head) {
+ action_result(pfn, MF_MSG_DIFFERENT_PAGE_SIZE, MF_IGNORED);
+ res = -EBUSY;
+ goto out;
+ }
+
page_flags = head->flags;
/*