From: James Houghton <jthoughton@google.com>
To: Will Deacon <will@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Muchun Song <muchun.song@linux.dev>,
Oscar Salvador <osalvador@suse.de>,
Andrew Morton <akpm@linux-foundation.org>
Cc: Nikos Nikoleris <nikos.nikoleris@arm.com>,
Linu Cherian <linu.cherian@arm.com>,
Mark Rutland <mark.rutland@arm.com>,
David Hildenbrand <david@kernel.org>,
Ryan Roberts <ryan.roberts@arm.com>,
Nanyong Sun <sunnanyong@huawei.com>, Yu Zhao <yuzhao@google.com>,
Frank van der Linden <fvdl@google.com>,
David Rientjes <rientjes@google.com>,
James Houghton <jthoughton@google.com>,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org
Subject: [PATCH v2 19/20 DO-NOT-MERGE] hugetlb_vmemmap: Add fault injection for in-place vmemmap PMD splits
Date: Sat, 3 Oct 2026 00:21:22 +0000 [thread overview]
Message-ID: <20261003002123.505555-20-jthoughton@google.com> (raw)
In-Reply-To: <20261003002123.505555-1-jthoughton@google.com>
Like try_update_vmemmap_pte(), try_populate_vmemmap_pmd() may fail,
e.g. on arm64 when replacing the block mapping keeps racing with
hardware access flag updates. HVO handles such failures by not
optimizing the folio.
Add a fault-injection capability, fail_hugetlb_vmemmap_pmd, alongside
fail_hugetlb_vmemmap_pte. When a fault is injected, the PMD split fails
with -EAGAIN without touching the page tables.
It can be configured through debugfs or through the
fail_hugetlb_vmemmap_pmd= boot option. Since vmemmap PMDs are only split
once, the boot option is the most effective way to exercise this path.
Assisted-by: LLM
Signed-off-by: James Houghton <jthoughton@google.com>
---
.../fault-injection/fault-injection.rst | 8 +++++---
lib/Kconfig.debug | 4 ++--
mm/hugetlb_vmemmap.c | 20 ++++++++++++++++++-
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/Documentation/fault-injection/fault-injection.rst b/Documentation/fault-injection/fault-injection.rst
index 403206645fa4..5cfabea811da 100644
--- a/Documentation/fault-injection/fault-injection.rst
+++ b/Documentation/fault-injection/fault-injection.rst
@@ -16,10 +16,11 @@ Available fault injection capabilities
injects page allocation failures. (alloc_pages(), get_free_pages(), ...)
-- fail_hugetlb_vmemmap_pte
+- fail_hugetlb_vmemmap_pte, fail_hugetlb_vmemmap_pmd
- injects failures of the in-place vmemmap PTE remaps done by HugeTLB vmemmap
- optimization. (try_update_vmemmap_pte())
+ injects failures of the in-place vmemmap PTE remaps and PMD splits done by
+ HugeTLB vmemmap optimization. (try_update_vmemmap_pte(),
+ try_populate_vmemmap_pmd())
- fail_usercopy
@@ -269,6 +270,7 @@ use the boot option::
failslab=
fail_page_alloc=
fail_hugetlb_vmemmap_pte=
+ fail_hugetlb_vmemmap_pmd=
fail_usercopy=
fail_make_request=
fail_futex=
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 96cd1f1da94a..7abda377c737 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2072,8 +2072,8 @@ config FAIL_HUGETLB_VMEMMAP
help
Provide fault-injection capability for the in-place vmemmap page
table updates done by HugeTLB vmemmap optimization (HVO), i.e.
- try_update_vmemmap_pte(). This exercises the rollback and
- partially-optimized folio paths.
+ try_update_vmemmap_pte() and try_populate_vmemmap_pmd(). This
+ exercises the rollback and partially-optimized folio paths.
config FAULT_INJECTION_USERCOPY
bool "Fault injection capability for usercopy functions"
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 9e0f52474bdb..f50880dd79a2 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -53,6 +53,7 @@ struct vmemmap_remap_walk {
#ifdef CONFIG_FAIL_HUGETLB_VMEMMAP
static DECLARE_FAULT_ATTR(fail_hugetlb_vmemmap_pte);
+static DECLARE_FAULT_ATTR(fail_hugetlb_vmemmap_pmd);
static int __init setup_fail_hugetlb_vmemmap_pte(char *str)
{
@@ -60,11 +61,19 @@ static int __init setup_fail_hugetlb_vmemmap_pte(char *str)
}
__setup("fail_hugetlb_vmemmap_pte=", setup_fail_hugetlb_vmemmap_pte);
+static int __init setup_fail_hugetlb_vmemmap_pmd(char *str)
+{
+ return setup_fault_attr(&fail_hugetlb_vmemmap_pmd, str);
+}
+__setup("fail_hugetlb_vmemmap_pmd=", setup_fail_hugetlb_vmemmap_pmd);
+
#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
static int __init fail_hugetlb_vmemmap_debugfs(void)
{
fault_create_debugfs_attr("fail_hugetlb_vmemmap_pte", NULL,
&fail_hugetlb_vmemmap_pte);
+ fault_create_debugfs_attr("fail_hugetlb_vmemmap_pmd", NULL,
+ &fail_hugetlb_vmemmap_pmd);
return 0;
}
late_initcall(fail_hugetlb_vmemmap_debugfs);
@@ -80,8 +89,17 @@ static int hvo_update_vmemmap_pte(unsigned long addr, pte_t *ptep, pte_t pte)
return -EAGAIN;
return try_update_vmemmap_pte(addr, ptep, pte);
}
+
+static int hvo_populate_vmemmap_pmd(unsigned long addr, pmd_t *pmdp,
+ pte_t *pgtable)
+{
+ if (should_fail(&fail_hugetlb_vmemmap_pmd, PMD_SIZE))
+ return -EAGAIN;
+ return try_populate_vmemmap_pmd(addr, pmdp, pgtable);
+}
#else
#define hvo_update_vmemmap_pte try_update_vmemmap_pte
+#define hvo_populate_vmemmap_pmd try_populate_vmemmap_pmd
#endif /* CONFIG_FAIL_HUGETLB_VMEMMAP */
static int vmemmap_split_pmd(pmd_t *pmd, struct page *head, unsigned long start,
@@ -113,7 +131,7 @@ static int vmemmap_split_pmd(pmd_t *pmd, struct page *head, unsigned long start,
if (likely(pmd_leaf(*pmd))) {
/* Make pte visible before pmd. See comment in pmd_install(). */
smp_wmb();
- ret = try_populate_vmemmap_pmd(start, pmd, pgtable);
+ ret = hvo_populate_vmemmap_pmd(start, pmd, pgtable);
if (ret)
goto free;
--
2.56.0.rc1.315.gc6ed9934b7-goog
next prev parent reply other threads:[~2026-10-03 0:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-03 0:21 [PATCH v2 00/20] Another attempt at HVO support on arm64 James Houghton
2026-10-03 0:21 ` [PATCH v2 01/20] hugetlb: Don't restore vmemmap of non-HVOed folios on bulk restore error James Houghton
2026-10-21 9:32 ` Muchun Song
2026-10-21 21:27 ` James Houghton
2026-10-22 2:17 ` Muchun Song
2026-10-03 0:21 ` [PATCH v2 02/20] arm64/pgtable: Clear AF with LDCLR on supported systems James Houghton
2026-10-03 0:21 ` [PATCH v2 03/20] hugetlb_vmemmap: Always flush TLB if needed upon PTE remapping James Houghton
2026-10-21 9:54 ` Muchun Song
2026-10-21 21:59 ` James Houghton
2026-10-22 9:18 ` Muchun Song
2026-10-22 17:44 ` James Houghton
2026-10-03 0:21 ` [PATCH v2 04/20] hugetlb_vmemmap: Leave pages partially HVOed upon restore failure James Houghton
2026-10-03 0:21 ` [PATCH v2 05/20] hugetlb_vmemmap: Use try_update_vmemmap_pte to update in-use PTEs James Houghton
2026-10-03 0:21 ` [PATCH v2 06/20] hugetlb_vmemmap: Allow architectures to dynamically disallow HVO James Houghton
2026-10-03 0:21 ` [PATCH v2 07/20] hugetlb_vmemmap: Disable HVO sysctl if arch doesn't support HVO James Houghton
2026-10-03 0:21 ` [PATCH v2 08/20] hugetlb: Fully initialize tail struct pages of non-pre-HVOed bootmem folios James Houghton
2026-10-03 0:21 ` [PATCH v2 09/20] hugetlb_vmemmap: Allow architectures to make HVO enablement boot-time only James Houghton
2026-10-03 0:21 ` [PATCH v2 10/20] hugetlb_vmemmap: Expose whether HVO is enabled to architecture code James Houghton
2026-10-03 0:21 ` [PATCH v2 11/20] arm64: Add bbm_through_af capability James Houghton
2026-10-03 0:21 ` [PATCH v2 12/20] arm64: Implement try_update_vmemmap_pte using the AF trick James Houghton
2026-10-03 0:21 ` [PATCH v2 13/20] arm64: Support hugetlb vmemmap optimization James Houghton
2026-10-03 0:21 ` [PATCH v2 14/20] hugetlb_vmemmap: Add fault injection for in-place vmemmap PTE updates James Houghton
2026-10-03 0:21 ` [PATCH v2 15/20] selftests/mm: Add HugeTLB vmemmap optimization stress test James Houghton
2026-10-03 0:21 ` [PATCH v2 16/20 DO-NOT-MERGE] hugetlb_vmemmap: Use try_populate_vmemmap_pmd for replacing in-use PMDs James Houghton
2026-10-03 0:21 ` [PATCH v2 17/20 DO-NOT-MERGE] arm64: Implement try_populate_vmemmap_pmd using AF trick James Houghton
2026-10-03 0:21 ` [PATCH v2 18/20 DO-NOT-MERGE] arm64: Drop BBML3 requirement for HVO James Houghton
2026-10-03 0:21 ` James Houghton [this message]
2026-10-03 0:21 ` [PATCH v2 20/20 DO-NOT-MERGE] selftests/mm: Add HVO pmd-split fault injection tests James Houghton
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=20261003002123.505555-20-jthoughton@google.com \
--to=jthoughton@google.com \
--cc=akpm@linux-foundation.org \
--cc=catalin.marinas@arm.com \
--cc=david@kernel.org \
--cc=fvdl@google.com \
--cc=linu.cherian@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mark.rutland@arm.com \
--cc=muchun.song@linux.dev \
--cc=nikos.nikoleris@arm.com \
--cc=osalvador@suse.de \
--cc=rientjes@google.com \
--cc=ryan.roberts@arm.com \
--cc=sunnanyong@huawei.com \
--cc=will@kernel.org \
--cc=yuzhao@google.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.