From: Jiaqi Yan <jiaqiyan@google.com>
To: linmiaohe@huawei.com, ljs@kernel.org, ziy@nvidia.com, vbabka@kernel.org
Cc: osalvador@kernel.org, harry.yoo@oracle.com, willy@infradead.org,
osalvador@suse.de, jackmanb@google.com, hannes@cmpxchg.org,
nao.horiguchi@gmail.com, david@kernel.org,
william.roche@oracle.com, tony.luck@intel.com,
wangkefeng.wang@huawei.com, jane.chu@oracle.com,
akpm@linux-foundation.org, muchun.song@linux.dev,
liam@infradead.org, rientjes@google.com, duenwen@google.com,
jthoughton@google.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, vbabka@suse.cz, rppt@kernel.org,
shuah@kernel.org, surenb@google.com, mhocko@suse.com,
boudewijn@delta-utec.com, Jiaqi Yan <jiaqiyan@google.com>
Subject: [PATCH v6 5/5] selftests/mm: add hard memory failure anonymous HugeTLB test
Date: Sun, 5 Jul 2026 18:07:14 +0000 [thread overview]
Message-ID: <20260705180714.3708947-6-jiaqiyan@google.com> (raw)
In-Reply-To: <20260705180714.3708947-1-jiaqiyan@google.com>
Add a new testcase to validate memory failure recovery for HWPoison
anonymous HugeTLB page, including proper SIGBUS delivery, releasing
a HugeTLB page containing one HWPoison page to buddy allocator, and
isolation of the raw HWPoison page.
The test uses HugeTLB's default hugesize.
Although can be added in future, this patch does not support testing
the MADV_SOFT variant.
Signed-off-by: Jiaqi Yan <jiaqiyan@google.com>
---
tools/testing/selftests/mm/memory-failure.c | 70 ++++++++++++++++++++-
1 file changed, 67 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/memory-failure.c b/tools/testing/selftests/mm/memory-failure.c
index 032ed952057c..78c105ce2af1 100644
--- a/tools/testing/selftests/mm/memory-failure.c
+++ b/tools/testing/selftests/mm/memory-failure.c
@@ -18,6 +18,7 @@
#include <linux/magic.h>
#include <errno.h>
+#include "hugepage_settings.h"
#include "vm_util.h"
enum inject_type {
@@ -27,6 +28,7 @@ enum inject_type {
enum result_type {
MADV_HARD_ANON,
+ MADV_HARD_ANON_HUGETLB,
MADV_HARD_CLEAN_PAGECACHE,
MADV_HARD_DIRTY_PAGECACHE,
MADV_SOFT_ANON,
@@ -47,6 +49,8 @@ FIXTURE(memory_failure)
int pagemap_fd;
int kpageflags_fd;
bool triggered;
+ /* Number of initial HugeTLB pages with default page size. */
+ unsigned long nr_hugetlb_pages;
};
FIXTURE_VARIANT(memory_failure)
@@ -157,6 +161,7 @@ static void check(struct __test_metadata *_metadata, FIXTURE_DATA(memory_failure
void *vaddr, enum result_type type, int setjmp)
{
unsigned long size;
+ unsigned long nr_hugetlb_pages;
uint64_t pfn_flags;
switch (type) {
@@ -174,6 +179,7 @@ static void check(struct __test_metadata *_metadata, FIXTURE_DATA(memory_failure
ASSERT_NE(pagemap_get_pfn(self->pagemap_fd, vaddr), self->pfn);
break;
case MADV_HARD_ANON:
+ case MADV_HARD_ANON_HUGETLB:
case MADV_HARD_DIRTY_PAGECACHE:
/* The SIGBUS signal should have been received. */
ASSERT_EQ(setjmp, 1);
@@ -184,8 +190,15 @@ static void check(struct __test_metadata *_metadata, FIXTURE_DATA(memory_failure
ASSERT_EQ(1UL << siginfo.si_addr_lsb, self->page_size);
ASSERT_EQ(siginfo.si_addr, vaddr);
- /* XXX Check backing pte is hwpoison entry when supported. */
- ASSERT_TRUE(pagemap_is_swapped(self->pagemap_fd, vaddr));
+ if (type != MADV_HARD_ANON_HUGETLB)
+ /*
+ * Check backing pte is hwpoison entry when supported.
+ * Although try_to_unmap_one() also installs hwpoison
+ * entry for HugeTLB, pagemap_hugetlb_range() doesn't
+ * parse swap entries at all.
+ */
+ ASSERT_TRUE(pagemap_is_swapped(self->pagemap_fd, vaddr));
+
break;
default:
SKIP(return, "unexpected inject type %d.\n", type);
@@ -193,7 +206,19 @@ static void check(struct __test_metadata *_metadata, FIXTURE_DATA(memory_failure
/* Check if the value of HardwareCorrupted has increased. */
ASSERT_EQ(get_hardware_corrupted_size(&size), 0);
- ASSERT_EQ(size, self->corrupted_size + self->page_size / 1024);
+
+ if (type == MADV_HARD_ANON_HUGETLB) {
+ /*
+ * Only one page is hardware corrupted; the rest should all be
+ * released to buddy allocator.
+ */
+ ASSERT_EQ(size, self->corrupted_size + getpagesize() / 1024);
+ /* HugeTLB should have lost the HWPoison HugeTLB page. */
+ nr_hugetlb_pages = hugetlb_nr_default_pages();
+ ASSERT_EQ(nr_hugetlb_pages + 1, self->nr_hugetlb_pages);
+ } else {
+ ASSERT_EQ(size, self->corrupted_size + self->page_size / 1024);
+ }
/* Check if HWPoison flag is set. */
ASSERT_EQ(pageflags_get(self->pfn, self->kpageflags_fd, &pfn_flags), 0);
@@ -247,6 +272,45 @@ TEST_F(memory_failure, anon)
ASSERT_EQ(munmap(addr, self->page_size), 0);
}
+TEST_F(memory_failure, anon_hugetlb)
+{
+ char *addr;
+ int ret;
+ const unsigned long nr_alloc_hugetlb_pages = 4;
+ unsigned long alloc_size;
+
+ if (variant->type == MADV_SOFT)
+ SKIP(return, "Soft offline test is not implemented");
+
+ /* HugeTLB settings will be automatically restored when test exits. */
+ hugetlb_setup_default(nr_alloc_hugetlb_pages);
+
+ alloc_size = default_huge_page_size() * nr_alloc_hugetlb_pages;
+ self->page_size = default_huge_page_size();
+ self->nr_hugetlb_pages = hugetlb_nr_default_pages();
+
+ addr = mmap(0, alloc_size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB, -1, 0);
+ if (addr == MAP_FAILED)
+ SKIP(return, "mmap failed, not enough memory or hugetlb not supported.\n");
+ memset(addr, 0xce, alloc_size);
+
+ prepare(_metadata, self, addr);
+
+ ret = sigsetjmp(signal_jmp_buf, 1);
+ if (!self->triggered) {
+ self->triggered = true;
+ ASSERT_EQ(variant->inject(self, addr), 0);
+ FORCE_READ(*addr);
+ }
+
+ check(_metadata, self, addr, MADV_HARD_ANON_HUGETLB, ret);
+
+ cleanup(_metadata, self, addr);
+
+ ASSERT_EQ(munmap(addr, alloc_size), 0);
+}
+
static int prepare_file(const char *fname, unsigned long size)
{
int fd;
--
2.55.0.rc0.799.gd6f94ed593-goog
next prev parent reply other threads:[~2026-07-05 18:07 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-05 18:07 [PATCH v6 0/5] Only free healthy pages in high-order has_hwpoisoned folio Jiaqi Yan
2026-07-05 18:07 ` [PATCH v6 1/5] mm/page_alloc: introduce __free_prepared_contig_range() with fpi_t Jiaqi Yan
2026-07-05 18:07 ` [PATCH v6 2/5] mm/page_alloc: only free healthy pages in high-order has_hwpoisoned folio Jiaqi Yan
2026-07-05 18:07 ` [PATCH v6 3/5] mm/memory-failure: set has_hwpoisoned flags on dissolved HugeTLB folio Jiaqi Yan
2026-07-05 18:07 ` [PATCH v6 4/5] mm/memory-failure: skip take_page_off_buddy after dissolving HWPoison HugeTLB page Jiaqi Yan
2026-07-05 18:07 ` Jiaqi Yan [this message]
2026-07-05 18:50 ` [PATCH v6 0/5] Only free healthy pages in high-order has_hwpoisoned folio Andrew Morton
2026-07-06 9:03 ` David Hildenbrand (Arm)
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=20260705180714.3708947-6-jiaqiyan@google.com \
--to=jiaqiyan@google.com \
--cc=akpm@linux-foundation.org \
--cc=boudewijn@delta-utec.com \
--cc=david@kernel.org \
--cc=duenwen@google.com \
--cc=hannes@cmpxchg.org \
--cc=harry.yoo@oracle.com \
--cc=jackmanb@google.com \
--cc=jane.chu@oracle.com \
--cc=jthoughton@google.com \
--cc=liam@infradead.org \
--cc=linmiaohe@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=muchun.song@linux.dev \
--cc=nao.horiguchi@gmail.com \
--cc=osalvador@kernel.org \
--cc=osalvador@suse.de \
--cc=rientjes@google.com \
--cc=rppt@kernel.org \
--cc=shuah@kernel.org \
--cc=surenb@google.com \
--cc=tony.luck@intel.com \
--cc=vbabka@kernel.org \
--cc=vbabka@suse.cz \
--cc=wangkefeng.wang@huawei.com \
--cc=william.roche@oracle.com \
--cc=willy@infradead.org \
--cc=ziy@nvidia.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox