All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Zaborowski <balrogg@gmail.com>
To: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@redhat.com>,
	Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
	Miaohe Lin <linmiaohe@huawei.com>
Subject: [PATCH] mm: avoid poison consumption when splitting THP
Date: Thu, 11 Sep 2025 04:14:01 +0200	[thread overview]
Message-ID: <20250911021401.734817-1-balrogg+code@gmail.com> (raw)

Handling a memory failure pointing inside a huge page requires splitting
the page.  The splitting logic uses a mechanism, implemented in
migrate.c:try_to_map_unused_to_zeropage(), that inspects contents of
individual pages to find zero-filled pages.  The read access to the
contents may cause a new, synchronous exception like an x86 Machine
Check, delivered before the initial memory_failure() finishes, ending
in a crash.

Luckily memory_failure() already sets the has_hwpoisoned flag on the
folio right before try_to_split_thp_page().  Don't enable the shared
zeropage mechanism (RMP_USE_SHARED_ZEROPAGE flag) down in
__split_unmapped_folio() when the original folio has has_hwpoisoned.

Note: we're disabling a potentially useful feature, some of the
individual pages that aren't poisoned might be zero-filled.  One
argument for not trying to add a mechanism to maybe re-scan them later,
apart from code cost, is that the owning process is likely being
killed and the memory released.

Signed-off-by: Andrew Zaborowski <balrogg+code@gmail.com>
---
 mm/huge_memory.c    | 3 ++-
 mm/memory-failure.c | 6 ++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 9c38a95e9f0..1568f0308b9 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3588,6 +3588,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
 		struct list_head *list, bool uniform_split)
 {
 	struct deferred_split *ds_queue = get_deferred_split_queue(folio);
+	bool has_hwpoisoned = folio_test_has_hwpoisoned(folio);
 	XA_STATE(xas, &folio->mapping->i_pages, folio->index);
 	struct folio *end_folio = folio_next(folio);
 	bool is_anon = folio_test_anon(folio);
@@ -3858,7 +3859,7 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
 	if (nr_shmem_dropped)
 		shmem_uncharge(mapping->host, nr_shmem_dropped);
 
-	if (!ret && is_anon)
+	if (!ret && is_anon && !has_hwpoisoned)
 		remap_flags = RMP_USE_SHARED_ZEROPAGE;
 	remap_page(folio, 1 << order, remap_flags);
 
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index fc30ca4804b..2d755493de9 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -2352,8 +2352,10 @@ int memory_failure(unsigned long pfn, int flags)
 		 * otherwise it may race with THP split.
 		 * And the flag can't be set in get_hwpoison_page() since
 		 * it is called by soft offline too and it is just called
-		 * for !MF_COUNT_INCREASED.  So here seems to be the best
-		 * place.
+		 * for !MF_COUNT_INCREASED.
+		 * It also tells __split_unmapped_folio() to not bother
+		 * using the shared zeropage -- the all-zeros check would
+		 * consume the poison.  So here seems to be the best place.
 		 *
 		 * Don't need care about the above error handling paths for
 		 * get_hwpoison_page() since they handle either free page
-- 
2.45.2



             reply	other threads:[~2025-09-11  2:16 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-11  2:14 Andrew Zaborowski [this message]
2025-09-11  3:19 ` [PATCH] mm: avoid poison consumption when splitting THP Zi Yan
2025-09-11  6:19   ` Lance Yang
2025-09-11  8:12 ` David Hildenbrand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250911021401.734817-1-balrogg+code@gmail.com \
    --to=balrogg@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@redhat.com \
    --cc=linmiaohe@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.