From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1E7AD37EFF0 for ; Sun, 5 Jul 2026 18:07:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783274843; cv=none; b=BQ7R2r6cvux5CmSMoAJds0M3EGs8ox+YlSM57WRic22O3olgYrR7EsIQVd58CEesrbCJ41PCqy0R57u5YVlqJ1WKtpc7oYUEPGsyE5UEsIBzPffeYXbVmaUPPOHYpRtm1mZDXFxjmfSVP4xlAH728W9m9Lb/oekAmrP1DrVgWq8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783274843; c=relaxed/simple; bh=o84WmN0Ji5OjIYFP1rN/m8MZYEvuNy0CoIT0VVl7+yM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fLTxwPO8lISU8bkUYdz0oap/ERCH+Vdk65y4AM0qI2wBUres6EhhcIm7zHPV7+cufXBi71Bp2hx5o7U2NnDDtYC+kc6aulHZz8z1yreOdh3l8PTfuOzBDeNusYHy9Vw8p7EOo4seo5pvwDuj/6BZIR3MDUTsgz8pwi9h8dhgI0Q= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jiaqiyan.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=kxxbjTA8; arc=none smtp.client-ip=209.85.210.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jiaqiyan.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kxxbjTA8" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-847a2509456so3840983b3a.1 for ; Sun, 05 Jul 2026 11:07:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1783274841; x=1783879641; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=rKIWvJIJG94eUvc0OXWaFW4RSMlfE+I0cCCIFWwNnGw=; b=kxxbjTA8LrqR0iBm/utLxCF9az03bDbgVDzyM6xK7K0w20x4UnQiXg8GDPiqIOEEoC Bixf2263v/L3KbiUppUi4bOzqtjv+EMWd8Bqn5CPUBC2d735aeOXq22/PlircUN9hmT9 BFLJ0cmfl9oHaBM14gZaKTChYjRUtsPCBXq+11pkaCDGUI12cnha46uJ50odfnzlSOgf CdU7rnrhspnnLcSn40JVpyhONABpG1IV+pAf0bz12GSfbONnB4k+gxxpGi9df1Z1xsYk BhBgO3sdJE7X6LF181fVhx8ffFOK6bP5lRbUHzKkvugncryc9+nYWNQjxq6v1BnPjo+R pSPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783274841; x=1783879641; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rKIWvJIJG94eUvc0OXWaFW4RSMlfE+I0cCCIFWwNnGw=; b=RcDMF9FZnh4UxtPaB5VngdzsEIdPuXFismUlDI5aS13ANexFvYezcid9dge54DKrOn 5KrDlXxnZowrUmXTmq18tuUC+kJ2D6TPAM8dh8j39pnhtV8eWNuKLsGr9l1UJGGE0+Nm /P0LdLlxGz9e5f5dNpAs61REl0opGCNqixAxDM0vP9Jpr5JpWMUZd6/BodgBCgj9hvsw fmiftO41kOuHbj2MIkdZEFQlJv6AddinXmqHFDfD3/H0RbNQ1W5nKVbloJaHujI1Hdc2 28AdQBxeZAt4b6xw5E/snmnlXuntm3ljhaFf79LMSdfckb4fDkXb6t0+zkH/SRC9i9Np MBLg== X-Forwarded-Encrypted: i=1; AHgh+RrWPcgU5dB6LbQtkLYYqjqSVZRvja4sVkWLSxns0QIDa2uOMQedt1/3E0as0Yhrl/e/dYIMbxV3MNSxaD8=@vger.kernel.org X-Gm-Message-State: AOJu0YwT746own6YhE1oQU5m/wikYU/gIletOGB02cAFl3TwI7F/5Gmj WJKuk32qKbccu6GlWPS3nJMP1C8sYUStxb7agq2SybipGi+XkBzBi6CFMeyGjwWAfFXwbmRmvh4 nu/94RF/0dOyoUg== X-Received: from pfjq21.prod.google.com ([2002:a05:6a00:895:b0:845:38af:5fa5]) (user=jiaqiyan job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a00:440c:b0:847:9e62:251 with SMTP id d2e1a72fcca58-847f6f73d82mr6633462b3a.54.1783274841203; Sun, 05 Jul 2026 11:07:21 -0700 (PDT) Date: Sun, 5 Jul 2026 18:07:14 +0000 In-Reply-To: <20260705180714.3708947-1-jiaqiyan@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260705180714.3708947-1-jiaqiyan@google.com> X-Mailer: git-send-email 2.55.0.rc0.799.gd6f94ed593-goog Message-ID: <20260705180714.3708947-6-jiaqiyan@google.com> Subject: [PATCH v6 5/5] selftests/mm: add hard memory failure anonymous HugeTLB test From: Jiaqi Yan 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 Content-Type: text/plain; charset="UTF-8" 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 --- 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 #include +#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