From: Luiz Capitulino <luizcap@redhat.com>
To: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
david@kernel.org, baolin.wang@linux.alibaba.com, ziy@nvidia.com,
lance.yang@linux.dev
Cc: corbet@lwn.net, tsbogend@alpha.franken.de, maddy@linux.ibm.com,
mpe@ellerman.id.au, agordeev@linux.ibm.com,
gerald.schaefer@linux.ibm.com, hca@linux.ibm.com,
gor@linux.ibm.com, x86@kernel.org, dave.hansen@linux.intel.com,
djbw@kernel.org, vishal.l.verma@intel.com, dave.jiang@intel.com,
akpm@linux-foundation.org, lorenzo.stoakes@oracle.com
Subject: Re: (sashiko review) Re: [PATCH v4 7/9] treewide: introduce arch_has_pmd_leaves()
Date: Wed, 6 May 2026 14:30:21 -0400 [thread overview]
Message-ID: <cff55de9-3689-4fa4-b468-59083958c2c5@redhat.com> (raw)
In-Reply-To: <415c4158-f87d-4a61-8aab-9f957b1fe1c8@redhat.com>
On 2026-05-06 14:22, Luiz Capitulino wrote:
> On 2026-05-01 15:18, Luiz Capitulino wrote:
>> Now that all the has_transparent_hugepage() callers have been converted
>> to pgtable_has_pmd_leaves(), this commit does two things:
>>
>> 1. Rename has_transparent_hugepage() arch implementations to
>> arch_has_pmd_leaves(), since that's what the helper checks for
>>
>> 2. Introduce the default implementation of arch_has_pmd_leaves() as
>> IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE). This means that if
>> the arch doesn't implement arch_has_pmd_leaves() we default to checking
>> CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE as a way to determine if
>> PMD-sized pages are supported
>>
>> Note that arch_has_pmd_leaves() is supposed to be called only by
>> init_arch_has_pmd_leaves(). The remaining exception is hugepage_init()
>> which will be converted in a future commit.
>>
>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>> ---
>> arch/mips/include/asm/pgtable.h | 4 ++--
>> arch/mips/mm/tlb-r4k.c | 4 ++--
>> arch/powerpc/include/asm/book3s/64/hash-4k.h | 2 +-
>> arch/powerpc/include/asm/book3s/64/hash-64k.h | 2 +-
>> arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +++++-----
>> arch/powerpc/include/asm/book3s/64/radix.h | 2 +-
>> arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++--
>> arch/s390/include/asm/pgtable.h | 4 ++--
>> arch/x86/include/asm/pgtable.h | 4 ++--
>> include/linux/pgtable.h | 4 ++--
>> mm/huge_memory.c | 2 +-
>> mm/memory.c | 2 +-
>> 12 files changed, 22 insertions(+), 22 deletions(-)
>>
>> diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
>> index fa7b935f947c..a97b788315e2 100644
>> --- a/arch/mips/include/asm/pgtable.h
>> +++ b/arch/mips/include/asm/pgtable.h
>> @@ -615,8 +615,8 @@ unsigned long io_remap_pfn_range_pfn(unsigned long pfn, unsigned long size);
>> /* We don't have hardware dirty/accessed bits, generic_pmdp_establish is fine.*/
>> #define pmdp_establish generic_pmdp_establish
>> -#define has_transparent_hugepage has_transparent_hugepage
>> -extern int has_transparent_hugepage(void);
>> +#define arch_has_pmd_leaves arch_has_pmd_leaves
>> +extern int arch_has_pmd_leaves(void);
>> static inline int pmd_trans_huge(pmd_t pmd)
>> {
>> diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
>> index 24fe85fa169d..c423b5784337 100644
>> --- a/arch/mips/mm/tlb-r4k.c
>> +++ b/arch/mips/mm/tlb-r4k.c
>> @@ -434,7 +434,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
>> #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>> -int has_transparent_hugepage(void)
>> +int arch_has_pmd_leaves(void)
>> {
>> static unsigned int mask = -1;
>> @@ -450,7 +450,7 @@ int has_transparent_hugepage(void)
>> }
>> return mask == PM_HUGE_MASK;
>> }
>> -EXPORT_SYMBOL(has_transparent_hugepage);
>> +EXPORT_SYMBOL(arch_has_pmd_leaves);
>> #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>> diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
>> index 8e5bd9902bed..6744c2287199 100644
>> --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
>> +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
>> @@ -165,7 +165,7 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
>> extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
>> extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
>> unsigned long addr, pmd_t *pmdp);
>> -extern int hash__has_transparent_hugepage(void);
>> +extern int hash__arch_has_pmd_leaves(void);
>> #endif
>> #endif /* !__ASSEMBLER__ */
>> diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h
>> index 7deb3a66890b..9392aba5e5dc 100644
>> --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
>> +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
>> @@ -278,7 +278,7 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
>> extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
>> extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
>> unsigned long addr, pmd_t *pmdp);
>> -extern int hash__has_transparent_hugepage(void);
>> +extern int hash__arch_has_pmd_leaves(void);
>> #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>> #endif /* __ASSEMBLER__ */
>> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
>> index e67e64ac6e8c..b6629c041e75 100644
>> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
>> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
>> @@ -1121,14 +1121,14 @@ static inline void update_mmu_cache_pud(struct vm_area_struct *vma,
>> {
>> }
>> -extern int hash__has_transparent_hugepage(void);
>> -static inline int has_transparent_hugepage(void)
>> +extern int hash__arch_has_pmd_leaves(void);
>> +static inline int arch_has_pmd_leaves(void)
>> {
>> if (radix_enabled())
>> - return radix__has_transparent_hugepage();
>> - return hash__has_transparent_hugepage();
>> + return radix__arch_has_pmd_leaves();
>> + return hash__arch_has_pmd_leaves();
>> }
>> -#define has_transparent_hugepage has_transparent_hugepage
>> +#define arch_has_pmd_leaves arch_has_pmd_leaves
>> static inline int has_transparent_pud_hugepage(void)
>> {
>> diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
>> index da954e779744..c884a119cbd9 100644
>> --- a/arch/powerpc/include/asm/book3s/64/radix.h
>> +++ b/arch/powerpc/include/asm/book3s/64/radix.h
>> @@ -298,7 +298,7 @@ extern pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm,
>> pud_t radix__pudp_huge_get_and_clear(struct mm_struct *mm,
>> unsigned long addr, pud_t *pudp);
>> -static inline int radix__has_transparent_hugepage(void)
>> +static inline int radix__arch_has_pmd_leaves(void)
>> {
>> /* For radix 2M at PMD level means thp */
>> if (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT)
>> diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c
>> index d9b5b751d7b7..88a4a2eab513 100644
>> --- a/arch/powerpc/mm/book3s64/hash_pgtable.c
>> +++ b/arch/powerpc/mm/book3s64/hash_pgtable.c
>> @@ -391,7 +391,7 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
>> return old_pmd;
>> }
>> -int hash__has_transparent_hugepage(void)
>> +int hash__arch_has_pmd_leaves(void)
>> {
>> if (!mmu_has_feature(MMU_FTR_16M_PAGE))
>> @@ -420,7 +420,7 @@ int hash__has_transparent_hugepage(void)
>> return 1;
>> }
>> -EXPORT_SYMBOL_GPL(hash__has_transparent_hugepage);
>> +EXPORT_SYMBOL_GPL(hash__arch_has_pmd_leaves);
>> #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
>> diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
>> index 2c6cee8241e0..33b165dbf3db 100644
>> --- a/arch/s390/include/asm/pgtable.h
>> +++ b/arch/s390/include/asm/pgtable.h
>> @@ -1799,8 +1799,8 @@ static inline int pmd_trans_huge(pmd_t pmd)
>> return pmd_leaf(pmd);
>> }
>> -#define has_transparent_hugepage has_transparent_hugepage
>> -static inline int has_transparent_hugepage(void)
>> +#define arch_has_pmd_leaves arch_has_pmd_leaves
>> +static inline int arch_has_pmd_leaves(void)
>> {
>> return cpu_has_edat1() ? 1 : 0;
>> }
>> diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
>> index 2187e9cfcefa..2edd6c9d789c 100644
>> --- a/arch/x86/include/asm/pgtable.h
>> +++ b/arch/x86/include/asm/pgtable.h
>> @@ -306,8 +306,8 @@ static inline int pud_trans_huge(pud_t pud)
>> }
>> #endif
>> -#define has_transparent_hugepage has_transparent_hugepage
>> -static inline int has_transparent_hugepage(void)
>> +#define arch_has_pmd_leaves arch_has_pmd_leaves
>> +static inline int arch_has_pmd_leaves(void)
>> {
>> return boot_cpu_has(X86_FEATURE_PSE);
>> }
>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>> index b365be3516bf..3d7eeb50c183 100644
>> --- a/include/linux/pgtable.h
>> +++ b/include/linux/pgtable.h
>> @@ -2273,8 +2273,8 @@ static inline void __init init_arch_has_pmd_leaves(void) { }
>> #endif
>> #endif
>> -#ifndef has_transparent_hugepage
>> -#define has_transparent_hugepage() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
>> +#ifndef arch_has_pmd_leaves
>> +#define arch_has_pmd_leaves() IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)
>> #endif
[Forgot to include the review, doing it now]
"""
When CONFIG_TRANSPARENT_HUGEPAGE is disabled, do we bypass crucial runtime
hardware feature checks on multiple architectures?
Because the architecture-specific declarations are often placed inside
CONFIG_TRANSPARENT_HUGEPAGE blocks (as seen above, and similarly in
arch/x86/include/asm/pgtable.h and arch/s390/include/asm/pgtable.h), they
will not be exposed to the generic headers when THP is disabled.
The preprocessor will then fall back to the default implementation here. Since
architectures like x86, s390, and powerpc select
HAVE_ARCH_TRANSPARENT_HUGEPAGE in their Kconfig independent of the THP
setting, this fallback evaluates to true.
Will this cause init_arch_has_pmd_leaves() to keep the static key enabled,
making pgtable_has_pmd_leaves() unconditionally return true at runtime even
when THP is disabled?
If this happens on older hardware without these features, could subsystems
like DAX that rely on pgtable_has_pmd_leaves() attempt to map PMD-sized
leaves and cause page table corruption or hardware exceptions?
"""
Although a bit of a corner case, this is a real issue.
Checking on x86, the problem is that the arch's implementation of
arch_has_pmd_leaves() lives inside a CONFIG_TRANSPARENT_HUGEPAGE block so
it won't be built when CONFIG_TRANSPARENT_HUGEPAGE=n which will cause
arch_has_pmd_leaves() to default to true without the proper hardware
check. I'll check the other archs and get this fixed.
>> #ifndef has_transparent_pud_hugepage
>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
>> index 970e077019b7..4da10e94bbb6 100644
>> --- a/mm/huge_memory.c
>> +++ b/mm/huge_memory.c
>> @@ -969,7 +969,7 @@ static int __init hugepage_init(void)
>> int err;
>> struct kobject *hugepage_kobj;
>> - if (!has_transparent_hugepage()) {
>> + if (!arch_has_pmd_leaves()) {
>> transparent_hugepage_flags = 1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED;
>> return -EINVAL;
>> }
>> diff --git a/mm/memory.c b/mm/memory.c
>> index 90b2d9e84320..c62fce83b8d0 100644
>> --- a/mm/memory.c
>> +++ b/mm/memory.c
>> @@ -169,7 +169,7 @@ EXPORT_SYMBOL(__arch_has_pmd_leaves_key);
>> void __init init_arch_has_pmd_leaves(void)
>> {
>> - if (!has_transparent_hugepage())
>> + if (!arch_has_pmd_leaves())
>> static_branch_disable(&__arch_has_pmd_leaves_key);
>> }
>
next prev parent reply other threads:[~2026-05-06 18:30 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-01 19:18 [PATCH v4 0/9] mm: thp: always enable mTHP support Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 1/9] docs: tmpfs: remove implementation detail reference Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 2/9] mm: introduce pgtable_has_pmd_leaves() Luiz Capitulino
2026-05-06 17:50 ` (sashiko review) " Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 3/9] drivers: dax: use pgtable_has_pmd_leaves() Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 4/9] drivers: nvdimm: " Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 5/9] mm: debug_vm_pgtable: " Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 6/9] mm: shmem: drop has_transparent_hugepage() usage Luiz Capitulino
2026-05-06 18:12 ` (sashiko review) " Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 7/9] treewide: introduce arch_has_pmd_leaves() Luiz Capitulino
2026-05-06 18:22 ` (sashiko review) " Luiz Capitulino
2026-05-06 18:30 ` Luiz Capitulino [this message]
2026-05-01 19:18 ` [PATCH v4 8/9] mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves() Luiz Capitulino
2026-05-01 19:18 ` [PATCH v4 9/9] mm: thp: always enable mTHP support Luiz Capitulino
2026-05-06 5:46 ` Baolin Wang
2026-05-06 18:34 ` (sashiko review) " Luiz Capitulino
2026-05-03 15:02 ` [PATCH v4 0/9] " Andrew Morton
2026-05-04 19:11 ` Luiz Capitulino
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=cff55de9-3689-4fa4-b468-59083958c2c5@redhat.com \
--to=luizcap@redhat.com \
--cc=agordeev@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=dave.jiang@intel.com \
--cc=david@kernel.org \
--cc=djbw@kernel.org \
--cc=gerald.schaefer@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=lance.yang@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=maddy@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=tsbogend@alpha.franken.de \
--cc=vishal.l.verma@intel.com \
--cc=x86@kernel.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