mm: thp: always enable mTHP support
Subsystems (13)
v8 cover mm: thp: always enable mTHP support
Introduction
============
Today, if an architecture implements has_transparent_hugepage() and the CPU lacks support for PMD-sized pages, the THP code disables all THP, including mTHP.
This happens because the has_transparent_hugepage() helper is overloaded:
its name implies it checks whether THP is enabled, but on some architectures it actually checks whether the CPU supports PMD-sized pages. In addition, the THP and shmem code have a big switch on has_transparent_hugepage().
This series solves this by decoupling THP availability checking from querying CPU support for PMD-sized pages. THP availability can be checked with IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE). For querying PMD-sized page support, this series introduces a new helper called pgtable_has_pmd_leaves(), which is independent of THP, has well defined semantics and can be used in fast paths.
Core THP code and shmem can use pgtable_has_pmd_leaves() to determine PMD-sized THP support at page fault time (or folio allocation time for shmem), leaving THP and shmem always enabled for other THP sizes. For architectures and CPUs that do support PMD-sized pages there's no intended change in behavior.
We also convert each user of has_transparent_hugepage(), and the related helper thp_disabled_by_hw(), to IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) and/or pgtable_has_pmd_leaves() according to the call site's check semantics. On s390, powerpc, mips and x86 the arch has_transparent_hugepage() implementation is moved out of the CONFIG_TRANSPARENT_HUGEPAGE guard and renamed to arch_has_pmd_leaves().
Thanks to David Hildenbrand for suggesting this improvement and for providing initial guidance (all bugs and misconceptions are mine).
This applies to mm-new 93f615a22169 ("mm/swap, PM: hibernate: atomically replace hibernation pin").
Reporting availability of PMD-sized pages to user-space
=======================================================
Before this series, not having PMD pages available would shut down THP support meaning that /sys/kernel/mm/transparent_hugepage would not be available. After this series, /sys/kernel/mm/transparent_hugepage and hpage_pmd_size are always available but hugepages-<PMD-size>kB is only available if PMD-sized pages are supported.
To me this seems logical, as hugepages-<size>kB is only available if <size> is supported. If this is correct, then MM kselftests that depend on PMD-sized pages will need to be updated to check for it as they fail with this series applied when PMD-sized pages are not available.
The alternative is changing hpage_pmd_size: either don't create the file when PMD-sized pages are not available or set hpage_pmd_size=0. My concern is that this could be considered an ABI breakage as this file was never reported to be optional or report a zero value.
Testing
=======
- Ran MM kselftests on x86_64 and s390
- Tested all mTHP sizes allocation on x86_64 (with and without PMD-sized pages available)
- Tested shmem with within_size w/ mTHP on x86_64 (with and without PMD-sized pages available)
- Performed defconfig build on x86_64, s390, arm64, powerpc, and mips
NOTES:
* I'm forcing arch_has_pmd_leaves() off on x86 to simulate not having PMD-sized pages available
* Running the MM kselftests when PMD pages are not available causes some tests that depend on PMD-sized THP pages to fail as noted earlier
Changelog
=========
v8
--
- Fixed build breakage on MIPS (Lance)
- Rebased on top of mm-new (fixed conflicts in include/linux/pgtable.h and mm/shmem.c - dropped a Reviewed-by as a result)
v7
--
- Applied on top of latest mm-new
- Improved various changelogs including cover-letter
- Changed arch_has_pmd_leaves() default implementation to use IS_ENABLED() instead of IS_BUILTIN()
v6
--
- Rebased on top of mm-unstable (required a minor conflict resolution)
- Added more Reviewed-by and Acked-by tags
v5
--
- Moved init_arch_has_pmd_leaves() to mm_core_init() (David)
- Renamed init_arch_has_pmd_leaves() to pgtable_leaf_support_init() (Lance)
- Added new patch changing shmem_getattr() to set blksize according to highest supported THP order (Baolin)
- Added new patches to move has_transparent_hugepage() out of CONFIG_TRANSPARENT_HUGEPAGE guards
- shmem_allowable_huge_orders(): rename variable and only disable PMD_ORDER (David)
- Added <linux/jmp_label.h> to include/linux/pgtable.h
- Added new tags and removed Reviewed-by from changed patches
v4
--
- Used static key for pgtable_has_pmd_leaves() API (Lance)
- Moved shmem pgtable_has_pmd_leaves() check to shmem_allowable_huge_orders() (Baolin)
- Default pgtable_has_pmd_leaves() implementation to IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE) (Zi)
- Dropped patch “mm: thp: x86: cleanup PSE feature bit usage” (Dave)
v3
--
- Rebased on top of latest Linus tree
- Removed i915 patch as driver dropped has_transparent_hugepage() usage
- Moved init_arch_has_pmd_leaves() call in start_kernel() to avoid conflict with early_param handlers clearing CPU feature flags
- Fixed build error with CONFIG_MMU=n (kernel test robot)
- Fixed huge_anon_orders_inherit default setting when !pgtable_has_pmd_leaves() (Baolin)
- Small commit changelog improvements
v2
--
- Added support for always enabling mTHPs for shmem (Baolin)
- Improved commits changelog & added reviewed-by
v1
--
- Call init_arch_has_pmd_leaves() from start_kernel()
- Keep pgtable_has_pmd_leaves() calls tied to CONFIG_TRANSPARENT_HUGEPAGE (David)
- Clear PUD_ORDER when clearing PMD_ORDER (David)
- Small changelog improvements (David)
- Rebased on top of latest mm-new
Luiz Capitulino (14):
docs: tmpfs: remove implementation detail reference
mm: shmem: shmem_getattr(): set blksize to highest supported THP order
mm: introduce pgtable_has_pmd_leaves()
drivers: dax: use pgtable_has_pmd_leaves()
drivers: nvdimm: use pgtable_has_pmd_leaves()
mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
mm: shmem: allow THP support determination at folio allocation time
s390: move has_transparent_hugepage() out of THP guard
powerpc: move has_transparent_hugepage() out of THP guard
mips: move has_transparent_hugepage() out of THP guard
x86: move has_transparent_hugepage() out of THP guard
treewide: introduce arch_has_pmd_leaves()
mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves()
mm: thp: always enable mTHP support
Documentation/filesystems/tmpfs.rst | 5 ++-- arch/mips/include/asm/pgtable.h | 6 ++-- arch/mips/mm/pgtable.c | 25 ++++++++++++++++ arch/mips/mm/tlb-r4k.c | 22 -------------- 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 | 18 ++++++------ arch/powerpc/include/asm/book3s/64/radix.h | 14 ++++----- arch/powerpc/mm/book3s64/hash_pgtable.c | 8 ++--- arch/s390/include/asm/pgtable.h | 6 ++-- arch/x86/include/asm/pgtable.h | 12 ++++---- drivers/dax/dax-private.h | 2 +- drivers/nvdimm/pfn_devs.c | 6 ++-- include/linux/huge_mm.h | 7 ----- include/linux/pgtable.h | 21 ++++++++++++-- mm/debug_vm_pgtable.c | 20 ++++++------- mm/huge_memory.c | 27 ++++++++++++----- mm/memory.c | 11 ++++++- mm/mm_init.c | 1 + mm/shmem.c | 29 ++++++++++++------- 20 files changed, 144 insertions(+), 100 deletions(-)
Signature · 1 line
2.55.0
PATCH v8 1/14 docs: tmpfs: remove implementation detail reference
The tmpfs.rst doc references the has_transparent_hugepage() helper, which is an implementation detail in the kernel and not relevant for users wishing to properly configure THP support for tmpfs. Remove it.
--- Documentation/filesystems/tmpfs.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
Documentation/filesystems/tmpfs.rst +2 -3
@@ -109,9 +109,8 @@ noswap Disables swap. Remounts must respect the original settings. ====== =========================================================== tmpfs also supports Transparent Huge Pages which requires a kernel -configured with CONFIG_TRANSPARENT_HUGEPAGE and with huge supported for -your system (has_transparent_hugepage(), which is architecture specific). -The mount options for this are: +configured with CONFIG_TRANSPARENT_HUGEPAGE and with huge pages +supported for your system. The mount options for this are: ================ ============================================================== huge=never Do not allocate huge pages. This is the default.
Signature · 1 line
2.55.0
PATCH v8 2/14 mm: shmem: shmem_getattr(): set blksize to highest supported THP order
In reply to Luiz CapitulinoToday, shmem_getattr() sets stat->blksize to PMD size whenever shmem_huge_global_enabled() returns non-zero. While this works fine for the normal THP-enabled case as explained by Baolin in [1], this has two problems:
1. Theoretically, when shmem is configured for within_size, this could set blksize to PMD size even though the allocation may be a smaller mTHP order
2. A future commit will allow shmem THP support to be enabled even when the CPU doesn't support PMD-sized pages. We should not allow blksize to be set to PMD size in this case
In order to fix #1 and prepare for #2, this commit sets blksize to the size of the highest supported order returned by shmem_huge_global_enabled().
[1] https://lore.kernel.org/linux-mm/[email protected]/
--- mm/shmem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
mm/shmem.c +4 -2
@@ -1506,6 +1506,7 @@ static int shmem_getattr(struct mnt_idmap *idmap, {struct inode *inode = path->dentry->d_inode;struct shmem_inode_info *info =SHMEM_I (inode); +unsigned int orders;/* Fast-path hint; recalc under info->lock corrects any stale read. */ if (data_race (info->alloced - info->swapped != inode->i_mapping->nrpages))
@@ -1522,8 +1523,9 @@ static int shmem_getattr(struct mnt_idmap *idmap, STATX_ATTR_NODUMP);generic_fillattr (idmap, request_mask, inode, stat); -if (shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 )) - stat->blksize =HPAGE_PMD_SIZE ; + orders =shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 ); +if (orders) + stat->blksize =PAGE_SIZE <<highest_order (orders);if (request_mask &STATX_BTIME ) { stat->result_mask |=STATX_BTIME ;
Signature · 1 line
2.55.0
Re: [PATCH v8 02/14] mm: shmem: shmem_getattr(): set blksize to highest supported THP order
Quoted 40 lines · Luiz Capitulino
Today,
shmem_getattr()setsstat->blksizeto PMD size whenevershmem_huge_global_enabled()returns non-zero. While this works fine for the normal THP-enabled case as explained by Baolin in [1], this has two problems:1. Theoretically, when shmem is configured for
within_size, this could set blksize to PMD size even though the allocation may be a smaller mTHP order2. A future commit will allow shmem THP support to be enabled even when the CPU doesn't support PMD-sized pages. We should not allow blksize to be set to PMD size in this case
In order to fix #1 and prepare for #2, this commit sets blksize to the size of the highest supported order returned by
shmem_huge_global_enabled().[1] https://lore.kernel.org/linux-mm/[email protected]/
Suggested-by Baolin Wang <[email protected]>Acked-by Zi Yan <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>--- mm/shmem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)mm/shmem.c +1
-0@@ -1506,6 +1506,7 @@ static int shmem_getattr(struct mnt_idmap *idmap, {struct inode *inode = path->dentry->d_inode;struct shmem_inode_info *info =SHMEM_I (inode); +unsigned int orders;/* Fast-path hint; recalc under info->lock corrects any stale read. */ if (data_race (info->alloced - info->swapped != inode->i_mapping->nrpages))@@ -1522,8 +1523,9 @@ static int shmem_getattr(struct mnt_idmap *idmap, STATX_ATTR_NODUMP);
mm/shmem.c static int shmem_getattr(struct mnt_idmap *idmap, · line 1531
Quoted 10 lines
mm/shmem.c +3
-2generic_fillattr (idmap, request_mask, inode, stat); -if (shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 )) - stat->blksize =HPAGE_PMD_SIZE ; + orders =shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 ); +if (orders) + stat->blksize =PAGE_SIZE <<highest_order (orders);if (request_mask &STATX_BTIME ) { stat->result_mask |=STATX_BTIME ;
Heh, looking into the history of this I stumble over
commit 89fdcd262fd40712da65e922558872a12b203332
Author: Yang Shi <[email protected]> Date: Thu Jun 7 17:06:59 2018 -0700
mm: shmem: make stat.st_blksize return huge page size if THP is on
Since tmpfs THP was supported in 4.8, hugetlbfs is not the only filesystem with huge page support anymore. tmpfs can use huge page via THP when mounting by "huge=" mount option.
Which is a good read, especially regarding Hugh's comments:
"
: Sorry, I have no enthusiasm for this patch; but do I feel strongly : enough to override you and everyone else to NAK it? No, I don't feel : that strongly, maybe st_blksize isn't worth arguing over.
:
: We did look at struct stat when designing huge tmpfs, to see if there : were any fields that should be adjusted for it; but concluded none. : Yes, it would sometimes be nice to have a quickly accessible indicator : for when tmpfs has been mounted huge (scanning /proc/mounts for options : can be tiresome, agreed); but since tmpfs tries to supply huge (or not) : pages transparently, no difference seemed right.
"
(I agree with Hugh, also I find it odd to indicate for THP something > PAGE_SIZE)
Anyhow, that ship has sailed.
Effectively, I think "stat->blksize" is not that relevant. But indeed, today it gives us the highest *possible* size we could see on that system.
shmem_huge_global_enabled() does not seem to depend on any runtime toggles that could change, only on inode properties.
So your change looks good to me.
Signature · 3 lines
Cheers, David
PATCH v8 3/14 mm: introduce pgtable_has_pmd_leaves()
In reply to Luiz CapitulinoCurrently, we have two helpers that check for PMD-sized pages but have different names and slightly different semantics:
- has_transparent_hugepage(): the name suggests it checks if THP is enabled, but when CONFIG_TRANSPARENT_HUGEPAGE=y and the architecture implements this helper, it actually checks if the CPU supports PMD-sized pages
- thp_disabled_by_hw(): the name suggests it checks if THP is disabled by the hardware, but it just returns a cached value acquired with has_transparent_hugepage() during boot. This helper is used in fast paths
A better design would be to separate CONFIG_TRANSPARENT_HUGEPAGE checking, which can be done with the IS_ENABLED() macro, from checking if a CPU supports PMD-sized pages.
To this end, this commit introduces a new helper called pgtable_has_pmd_leaves() which offers the following advantages:
1. Well defined and clear semantics: it returns true if the CPU supports PMD-sized pages and false otherwise
2. It always returns a cached value, so it can be used in fast paths
3. It's implemented with a static key: it's a no-op for archs not implemeting it and for archs implementing it the static key is changed only during boot
The new helper requires an initialization step which is performed by pgtable_leaf_support_init(). We call pgtable_leaf_support_init() early during boot from mm_core_init().
The next commits will convert users of both has_transparent_hugepage() and thp_disabled_by_hw() to pgtable_has_pmd_leaves() and/or IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE).
--- include/linux/pgtable.h | 17 +++++++++++++++++ mm/memory.c | 9 +++++++++ mm/mm_init.c | 1 + 3 files changed, 27 insertions(+)
include/linux/pgtable.h +17 -0
@@ -14,6 +14,7 @@#include <linux/mm_types.h> #include <linux/bug.h> #include <linux/errno.h> +#include <linux/jump_label.h> #include <asm-generic/pgtable_uffd.h> #include <linux/page_table_check.h>
@@ -2327,6 +2328,22 @@ void ptval_bytes_to_hex_str(char *buf, size_t buf_size, const void *entry, size_#else #define PTVAL_STR_MAX (16 + 1)/* Max 64-bit value in hex + NUL */ #endif + +#ifdef CONFIG_MMU +DECLARE_STATIC_KEY_TRUE (__arch_has_pmd_leaves_key); +static inline bool pgtable_has_pmd_leaves (void ) +{ +return static_branch_likely (&__arch_has_pmd_leaves_key); +} +void __init pgtable_leaf_support_init (void ); +#else +static inline bool pgtable_has_pmd_leaves (void ) +{ +return false; +} +static inline void __init pgtable_leaf_support_init (void ) { } +#endif +#endif /* !__ASSEMBLER__ */ #if !defined(MAX_POSSIBLE_PHYSMEM_BITS ) && !defined(CONFIG_64BIT )
mm/memory.c +9 -0
@@ -164,6 +164,15 @@ __setup("norandmaps", disable_randmaps);unsigned long highest_memmap_pfn__read_mostly ; +DEFINE_STATIC_KEY_TRUE (__arch_has_pmd_leaves_key); +EXPORT_SYMBOL (__arch_has_pmd_leaves_key); + +void __init pgtable_leaf_support_init (void ) +{ +if (!has_transparent_hugepage ()) +static_branch_disable (&__arch_has_pmd_leaves_key); +} +void mm_trace_rss_stat (struct mm_struct *mm,int member) {trace_rss_stat (mm, member);
mm/mm_init.c +1 -0
@@ -2693,6 +2693,7 @@ void __init mm_core_init(void) {arch_mm_preinit ();init_zero_page_pfn (); +pgtable_leaf_support_init ();/* Initializations relying on SMP setup */ BUILD_BUG_ON (MAX_ZONELISTS >2 );
Signature · 1 line
2.55.0
Re: [PATCH v8 03/14] mm: introduce pgtable_has_pmd_leaves()
Quoted 35 lines · Luiz Capitulino
Currently, we have two helpers that check for PMD-sized pages but have different names and slightly different semantics:
-
has_transparent_hugepage(): the name suggests it checks if THP is enabled, but whenCONFIG_TRANSPARENT_HUGEPAGE=yand the architecture implements this helper, it actually checks if the CPU supports PMD-sized pages-
thp_disabled_by_hw(): the name suggests it checks if THP is disabled by the hardware, but it just returns a cached value acquired withhas_transparent_hugepage()during boot. This helper is used in fast pathsA better design would be to separate
CONFIG_TRANSPARENT_HUGEPAGEchecking, which can be done with theIS_ENABLED()macro, from checking if a CPU supports PMD-sized pages.To this end, this commit introduces a new helper called
pgtable_has_pmd_leaves()which offers the following advantages:1. Well defined and clear semantics: it returns true if the CPU supports PMD-sized pages and false otherwise
2. It always returns a cached value, so it can be used in fast paths
3. It's implemented with a static key: it's a no-op for archs not implemeting it and for archs implementing it the static key is changed only during bootThe new helper requires an initialization step which is performed by
pgtable_leaf_support_init(). We callpgtable_leaf_support_init()early during boot frommm_core_init().The next commits will convert users of both
has_transparent_hugepage()andthp_disabled_by_hw()topgtable_has_pmd_leaves()and/orIS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE).
Quoted 7 lines
Signed-off-by Luiz Capitulino <[email protected]>--- include/linux/pgtable.h | 17 +++++++++++++++++ mm/memory.c | 9 +++++++++ mm/mm_init.c | 1 + 3 files changed, 27 insertions(+)
LGTM.
Signature · 2 lines
Best Regards, Yan, Zi
Re: [PATCH v8 03/14] mm: introduce pgtable_has_pmd_leaves()
In reply to Luiz CapitulinoQuoted 31 lines · Luiz Capitulino
Currently, we have two helpers that check for PMD-sized pages but have different names and slightly different semantics:
-
has_transparent_hugepage(): the name suggests it checks if THP is enabled, but whenCONFIG_TRANSPARENT_HUGEPAGE=yand the architecture implements this helper, it actually checks if the CPU supports PMD-sized pages-
thp_disabled_by_hw(): the name suggests it checks if THP is disabled by the hardware, but it just returns a cached value acquired withhas_transparent_hugepage()during boot. This helper is used in fast pathsA better design would be to separate
CONFIG_TRANSPARENT_HUGEPAGEchecking, which can be done with theIS_ENABLED()macro, from checking if a CPU supports PMD-sized pages.To this end, this commit introduces a new helper called
pgtable_has_pmd_leaves()which offers the following advantages:1. Well defined and clear semantics: it returns true if the CPU supports PMD-sized pages and false otherwise
2. It always returns a cached value, so it can be used in fast paths
3. It's implemented with a static key: it's a no-op for archs not implemeting it and for archs implementing it the static key is changed only during bootThe new helper requires an initialization step which is performed by
pgtable_leaf_support_init(). We callpgtable_leaf_support_init()early during boot frommm_core_init().
Quoted 6 lines
The next commits will convert users of both
has_transparent_hugepage()andthp_disabled_by_hw()topgtable_has_pmd_leaves()and/orIS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE).Signed-off-by Luiz Capitulino <[email protected]>---
Clean, thanks
Signature · 3 lines
Cheers, David
PATCH v8 4/14 drivers: dax: use pgtable_has_pmd_leaves()
In reply to Luiz Capitulinodax_align_valid() uses has_transparent_hugepage() to check if PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
--- drivers/dax/dax-private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dax/dax-private.h +1 -1
@@ -121,7 +121,7 @@ static inline bool dax_align_valid(unsigned long align) {if (align ==PUD_SIZE &&IS_ENABLED (CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD ))return true; -if (align ==PMD_SIZE &&has_transparent_hugepage ()) +if (align ==PMD_SIZE &&pgtable_has_pmd_leaves ())return true;if (align ==PAGE_SIZE )return true;
Signature · 1 line
2.55.0
Re: [PATCH v8 04/14] drivers: dax: use pgtable_has_pmd_leaves()
Quoted 9 lines · Luiz Capitulino
dax_align_valid()useshas_transparent_hugepage()to check if PMD-sized pages are supported, usepgtable_has_pmd_leaves()instead.Signed-off-by Luiz Capitulino <[email protected]>--- drivers/dax/dax-private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
LGTM.
Signature · 2 lines
Best Regards, Yan, Zi
David Hildenbrand (Arm)
maintainerRe: [PATCH v8 04/14] drivers: dax: use pgtable_has_pmd_leaves()
In reply to Luiz CapitulinoQuoted 14 lines · Luiz Capitulino
dax_align_valid()useshas_transparent_hugepage()to check if PMD-sized pages are supported, usepgtable_has_pmd_leaves()instead.Signed-off-by Luiz Capitulino <[email protected]>--- drivers/dax/dax-private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/dax/dax-private.h +0
-0
drivers/dax/dax-private.h static inline bool dax_align_valid(unsigned long align) · line 127
Quoted 8 lines
drivers/dax/dax-private.h +1
-1@@ -121,7 +121,7 @@ static inline bool dax_align_valid(unsigned long align) {if (align ==PUD_SIZE &&IS_ENABLED (CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD ))return true; -if (align ==PMD_SIZE &&has_transparent_hugepage ()) +if (align ==PMD_SIZE &&pgtable_has_pmd_leaves ())return true;if (align ==PAGE_SIZE )return true;
The main part why we don't see any change is that dax_align_valid() is wrapped in the #ifdef CONFIG_TRANSPARENT_HUGEPAGE today.
Might we worth spelling that out in the patch description.
Signature · 3 lines
Cheers, David
Re: [PATCH v8 04/14] drivers: dax: use pgtable_has_pmd_leaves()
Quoted 27 lines · David Hildenbrand (Arm)
Quoted 14 lines · Luiz Capitulino
dax_align_valid()useshas_transparent_hugepage()to check if PMD-sized pages are supported, usepgtable_has_pmd_leaves()instead.Signed-off-by Luiz Capitulino <[email protected]>--- drivers/dax/dax-private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/dax/dax-private.h +0
-0drivers/dax/dax-private.h static inline bool dax_align_valid(unsigned long align) · line 127
Quoted 8 lines
drivers/dax/dax-private.h +1
-1@@ -121,7 +121,7 @@ static inline bool dax_align_valid(unsigned long align) {if (align ==PUD_SIZE &&IS_ENABLED (CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD ))return true; -if (align ==PMD_SIZE &&has_transparent_hugepage ()) +if (align ==PMD_SIZE &&pgtable_has_pmd_leaves ())return true;if (align ==PAGE_SIZE )return true;The main part why we don't see any change is that
dax_align_valid()is wrapped in the #ifdefCONFIG_TRANSPARENT_HUGEPAGEtoday.
Quoted 1 line
Might we worth spelling that out in the patch description.
OK, the new changelog reads:
"""dax_align_valid() uses has_transparent_hugepage() to check if PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
No functional change intended since the call happens under the CONFIG_TRANSPARENT_HUGEPAGE guard and when CONFIG_TRANSPARENT_HUGEPAGE=y both functions return the same value.
"""
PATCH v8 5/14 drivers: nvdimm: use pgtable_has_pmd_leaves()
In reply to Luiz Capitulinond_pfn_supported_alignments() and nd_pfn_default_alignment() use has_transparent_hugepage() to check if THP is supported with PMD-sized pages. Use pgtable_has_pmd_leaves() instead. Also, check for IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) to preserve the current implementation semantics.
--- drivers/nvdimm/pfn_devs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/nvdimm/pfn_devs.c +4 -2
@@ -94,7 +94,8 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments) alignments[0 ] =PAGE_SIZE ; -if (has_transparent_hugepage ()) { +if (IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && +pgtable_has_pmd_leaves ()) { alignments[1 ] =HPAGE_PMD_SIZE ;if (has_transparent_pud_hugepage ()) alignments[2 ] =HPAGE_PUD_SIZE ;
@@ -109,7 +110,8 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)static unsigned long nd_pfn_default_alignment (void ) { -if (has_transparent_hugepage ()) +if (IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && +pgtable_has_pmd_leaves ())return HPAGE_PMD_SIZE ;return PAGE_SIZE ; }
Signature · 1 line
2.55.0
Re: [PATCH v8 05/14] drivers: nvdimm: use pgtable_has_pmd_leaves()
Quoted 17 lines · Luiz Capitulino
nd_pfn_supported_alignments()andnd_pfn_default_alignment()usehas_transparent_hugepage()to check if THP is supported with PMD-sized pages. Usepgtable_has_pmd_leaves()instead. Also, check forIS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)to preserve the current implementation semantics.Acked-by Zi Yan <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>--- drivers/nvdimm/pfn_devs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)drivers/nvdimm/pfn_devs.c +0
-0
drivers/nvdimm/pfn_devs.c static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments) · line 98
Quoted 6 lines
drivers/nvdimm/pfn_devs.c +2
-1@@ -94,7 +94,8 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments) alignments[0 ] =PAGE_SIZE ; -if (has_transparent_hugepage ()) { +if (IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && +pgtable_has_pmd_leaves ()) {
Not sure if I mentioned it but we *could* provide a helper that checks for THP PMD order support. But I would only add that if really used frequently.
Scanning your other patches, that doesn't seem to be the case :)
Signature · 3 lines
Cheers, David
PATCH v8 6/14 mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
In reply to Luiz Capitulinodebug_vm_pgtable calls has_transparent_hugepage() in multiple places to check if PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
--- mm/debug_vm_pgtable.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
mm/debug_vm_pgtable.c +10 -10
@@ -177,7 +177,7 @@ static void __init pmd_basic_tests(struct pgtable_debug_args *args, int idx)unsigned long val = idx, *ptr = &val;pmd_t pmd; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ;pr_debug ("Validating PMD basic (%pGv)\n" , ptr);
@@ -222,7 +222,7 @@ static void __init pmd_advanced_tests(struct pgtable_debug_args *args)pmd_t pmd;unsigned long vaddr = args->vaddr; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ; page = (args->pmd_pfn !=ULONG_MAX ) ?pfn_to_page (args->pmd_pfn) :NULL ;
@@ -283,7 +283,7 @@ static void __init pmd_leaf_tests(struct pgtable_debug_args *args) {pmd_t pmd; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ;pr_debug ("Validating PMD leaf\n" );
@@ -688,7 +688,7 @@ static void __init pmd_protnone_tests(struct pgtable_debug_args *args)if (!IS_ENABLED (CONFIG_ARCH_HAS_PTE_PROTNONE ))return ; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ;pr_debug ("Validating PMD protnone\n" );
@@ -737,7 +737,7 @@ static void __init pmd_soft_dirty_tests(struct pgtable_debug_args *args)if (!pgtable_supports_soft_dirty ())return ; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ;pr_debug ("Validating PMD soft dirty\n" );
@@ -754,7 +754,7 @@ static void __init pmd_leaf_soft_dirty_tests(struct pgtable_debug_args *args) !IS_ENABLED(CONFIG_ARCH_HAS_PMD_SOFTLEAVES)) return; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ;pr_debug ("Validating PMD swap soft dirty\n" );
@@ -825,7 +825,7 @@ static void __init pmd_softleaf_tests(struct pgtable_debug_args *args)swp_entry_t arch_entry;pmd_t pmd1, pmd2; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ;pr_debug ("Validating PMD swap\n" );
@@ -906,7 +906,7 @@ static void __init pmd_thp_tests(struct pgtable_debug_args *args) {pmd_t pmd; -if (!has_transparent_hugepage ()) +if (!pgtable_has_pmd_leaves ())return ;pr_debug ("Validating PMD based THP\n" );
@@ -997,7 +997,7 @@ static void __init destroy_args(struct pgtable_debug_args *args) }if (IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && -has_transparent_hugepage () && +pgtable_has_pmd_leaves () && args->pmd_pfn !=ULONG_MAX ) {debug_vm_pgtable_free_huge_page (args, args->pmd_pfn,HPAGE_PMD_ORDER ); args->pmd_pfn =ULONG_MAX ;
@@ -1249,7 +1249,7 @@ static int __init init_args(struct pgtable_debug_args *args) }if (IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && -has_transparent_hugepage ()) { +pgtable_has_pmd_leaves ()) { page =debug_vm_pgtable_alloc_huge_page (args,HPAGE_PMD_ORDER );if (page) { args->pmd_pfn =page_to_pfn (page);
Signature · 1 line
2.55.0
Re: [PATCH v8 06/14] mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
Quoted 8 lines · Luiz Capitulino
debug_vm_pgtablecallshas_transparent_hugepage()in multiple places to check if PMD-sized pages are supported, usepgtable_has_pmd_leaves()instead.Reviewed-by Lance Yang <[email protected]>Reviewed-by Zi Yan <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>---
Best to mention in the description that there is no effective change as all calls to has_transparent_hugepage() are predicated by CONFIG_TRANSPARENT_HUGEPAGE.
Signature · 3 lines
Cheers, David
Re: [PATCH v8 06/14] mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
Quoted 5 lines · David Hildenbrand (Arm)
Quoted 4 lines · Luiz Capitulino
debug_vm_pgtablecallshas_transparent_hugepage()in multiple places to check if PMD-sized pages are supported, usepgtable_has_pmd_leaves()instead.
Quoted 7 lines
Quoted 4 lines
Reviewed-by Lance Yang <[email protected]>Reviewed-by Zi Yan <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>---
Best to mention in the description that there is no effective change as all calls to
has_transparent_hugepage()are predicated byCONFIG_TRANSPARENT_HUGEPAGE.
OK, the new changelog reads:
"""debug_vm_pgtable calls has_transparent_hugepage() in multiple places to check if PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
No functional change intended since the call happens under the CONFIG_TRANSPARENT_HUGEPAGE guard and when CONFIG_TRANSPARENT_HUGEPAGE=y both functions return the same value.
"""
Quoted 2 lines
PATCH v8 7/14 mm: shmem: allow THP support determination at folio allocation time
In reply to Luiz CapitulinoIn order to enable THP support in shmem today, besides the user configuration required, the CPU must support PMD-sized pages. This is the case because of the following has_transparent_hugepage() usage:
- shmem_parse_one() and shmem_parse_huge(): Check if THP is built-in and if the CPU supports PMD-sized pages
- shmem_init(): Since the CONFIG_TRANSPARENT_HUGEPAGE guard is outside the code block calling has_transparent_hugepage(), the has_transparent_hugepage() call is exclusively checking if the CPU supports PMD-sized pages
While it's necessary to check if CONFIG_TRANSPARENT_HUGEPAGE is enabled in all cases, shmem can determine THP size support at folio allocation time. Therefore, drop the has_transparent_hugepage() usage listed above while keeping the CONFIG_TRANSPARENT_HUGEPAGE checks.
Additionally, we need to check if PMD size order is supported in shmem_getattr(). Use pgtable_has_pmd_leaves() for that.
--- mm/shmem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
mm/shmem.c +5 -4
@@ -690,7 +690,7 @@ static int shmem_parse_huge(const char *str)else return -EINVAL ; -if (!has_transparent_hugepage () && +if (!IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && huge !=SHMEM_HUGE_NEVER && huge !=SHMEM_HUGE_DENY )return -EINVAL ;
@@ -1524,6 +1524,8 @@ static int shmem_getattr(struct mnt_idmap *idmap,generic_fillattr (idmap, request_mask, inode, stat); orders =shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 ); +if (!pgtable_has_pmd_leaves ()) + orders &= ~BIT (PMD_ORDER );if (orders) stat->blksize =PAGE_SIZE <<highest_order (orders);
@@ -4814,8 +4816,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)case Opt_huge: ctx->huge = result.uint_32;if (ctx->huge !=SHMEM_HUGE_NEVER && - !(IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && -has_transparent_hugepage ())) + !IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE )) goto unsupported_parameter; ctx->seen |=SHMEM_SEEN_HUGE ;break ;
@@ -5620,7 +5621,7 @@ void __init shmem_init(void)#endif #ifdef CONFIG_TRANSPARENT_HUGEPAGE -if (has_transparent_hugepage () && shmem_huge >SHMEM_HUGE_DENY ) +if (shmem_huge >SHMEM_HUGE_DENY )SHMEM_SB (shm_mnt->mnt_sb)->huge = shmem_huge;else shmem_huge =SHMEM_HUGE_NEVER ;/* just in case it was patched */
Signature · 1 line
2.55.0
Re: [PATCH v8 07/14] mm: shmem: allow THP support determination at folio allocation time
Quoted 32 lines · Luiz Capitulino
In order to enable THP support in shmem today, besides the user configuration required, the CPU must support PMD-sized pages. This is the case because of the following
has_transparent_hugepage()usage:-
shmem_parse_one()andshmem_parse_huge(): Check if THP is built-in and if the CPU supports PMD-sized pages-
shmem_init(): Since theCONFIG_TRANSPARENT_HUGEPAGEguard is outside the code block callinghas_transparent_hugepage(), thehas_transparent_hugepage()call is exclusively checking if the CPU supports PMD-sized pagesWhile it's necessary to check if
CONFIG_TRANSPARENT_HUGEPAGEis enabled in all cases, shmem can determine THP size support at folio allocation time. Therefore, drop thehas_transparent_hugepage()usage listed above while keeping theCONFIG_TRANSPARENT_HUGEPAGEchecks.Additionally, we need to check if PMD size order is supported in
shmem_getattr(). Usepgtable_has_pmd_leaves()for that.Reviewed-by Baolin Wang <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>--- mm/shmem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)mm/shmem.c +0
-0
mm/shmem.c static int shmem_parse_huge(const char *str) · line 695
Quoted 7 lines
mm/shmem.c +1
-1@@ -690,7 +690,7 @@ static int shmem_parse_huge(const char *str)else return -EINVAL ; -if (!has_transparent_hugepage () && +if (!IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && huge !=SHMEM_HUGE_NEVER && huge !=SHMEM_HUGE_DENY )return -EINVAL ;
This can be deleted, since shmem_parse_huge() is guarded by CONFIG_TRANSPARENT_HUGEPAGE and after the change the if is always false under that guard.
Otherwise, LGTM. With the above code deleted, feel free to add
Signature · 2 lines
Best Regards, Yan, Zi
Re: [PATCH v8 07/14] mm: shmem: allow THP support determination at folio allocation time
Quoted 45 lines · Zi Yan
Quoted 32 lines · Luiz Capitulino
In order to enable THP support in shmem today, besides the user configuration required, the CPU must support PMD-sized pages. This is the case because of the following
has_transparent_hugepage()usage:-
shmem_parse_one()andshmem_parse_huge(): Check if THP is built-in and if the CPU supports PMD-sized pages-
shmem_init(): Since theCONFIG_TRANSPARENT_HUGEPAGEguard is outside the code block callinghas_transparent_hugepage(), thehas_transparent_hugepage()call is exclusively checking if the CPU supports PMD-sized pagesWhile it's necessary to check if
CONFIG_TRANSPARENT_HUGEPAGEis enabled in all cases, shmem can determine THP size support at folio allocation time. Therefore, drop thehas_transparent_hugepage()usage listed above while keeping theCONFIG_TRANSPARENT_HUGEPAGEchecks.Additionally, we need to check if PMD size order is supported in
shmem_getattr(). Usepgtable_has_pmd_leaves()for that.Reviewed-by Baolin Wang <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>--- mm/shmem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)mm/shmem.c +0
-0mm/shmem.c static int shmem_parse_huge(const char *str) · line 695
Quoted 7 lines
mm/shmem.c +1
-1@@ -690,7 +690,7 @@ static int shmem_parse_huge(const char *str)else return -EINVAL ; -if (!has_transparent_hugepage () && +if (!IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && huge !=SHMEM_HUGE_NEVER && huge !=SHMEM_HUGE_DENY )return -EINVAL ;This can be deleted, since
shmem_parse_huge()is guarded byCONFIG_TRANSPARENT_HUGEPAGEand after the change the if is always false under that guard.
Quoted 3 lines
Otherwise, LGTM. With the above code deleted, feel free to add
Reviewed-by Zi Yan <[email protected]>
OK, here's the diff:
mm/shmem.c +0 -4
@@ -690,10 +690,6 @@ static int shmem_parse_huge(const char *str)else return -EINVAL ; -if (!IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && - huge !=SHMEM_HUGE_NEVER && huge !=SHMEM_HUGE_DENY ) -return -EINVAL ; -/* Do not override huge allocation policy with non-PMD sized mTHP */ if (huge ==SHMEM_HUGE_FORCE && huge_shmem_orders_inherit !=BIT (HPAGE_PMD_ORDER ))
David Hildenbrand (Arm)
maintainerRe: [PATCH v8 07/14] mm: shmem: allow THP support determination at folio allocation time
In reply to Luiz CapitulinoQuoted 41 lines · Luiz Capitulino
In order to enable THP support in shmem today, besides the user configuration required, the CPU must support PMD-sized pages. This is the case because of the following
has_transparent_hugepage()usage:-
shmem_parse_one()andshmem_parse_huge(): Check if THP is built-in and if the CPU supports PMD-sized pages-
shmem_init(): Since theCONFIG_TRANSPARENT_HUGEPAGEguard is outside the code block callinghas_transparent_hugepage(), thehas_transparent_hugepage()call is exclusively checking if the CPU supports PMD-sized pagesWhile it's necessary to check if
CONFIG_TRANSPARENT_HUGEPAGEis enabled in all cases, shmem can determine THP size support at folio allocation time. Therefore, drop thehas_transparent_hugepage()usage listed above while keeping theCONFIG_TRANSPARENT_HUGEPAGEchecks.Additionally, we need to check if PMD size order is supported in
shmem_getattr(). Usepgtable_has_pmd_leaves()for that.Reviewed-by Baolin Wang <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>--- mm/shmem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)mm/shmem.c +1
-1@@ -690,7 +690,7 @@ static int shmem_parse_huge(const char *str)else return -EINVAL ; -if (!has_transparent_hugepage () && +if (!IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && huge !=SHMEM_HUGE_NEVER && huge !=SHMEM_HUGE_DENY )return -EINVAL ;
mm/shmem.c static int shmem_getattr(struct mnt_idmap *idmap, · line 1526
Quoted 3 lines
mm/shmem.c +0
-0@@ -1524,6 +1524,8 @@ static int shmem_getattr(struct mnt_idmap *idmap,generic_fillattr (idmap, request_mask, inode, stat); orders =shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 );
I'm curious: why is that not handled inside shmem_huge_global_enabled() ? If PMD order is impossible (well, okay, it is possible, but we simply cannot map these things through PMDs), I would expect that we never list them as "enabled".
(while shmem could allocate PMD folios, it would have to map them always through PTEs. I think this would be possible through some changes, but we can defer that to some future work).
Signature · 3 lines
Cheers, David
Re: [PATCH v8 07/14] mm: shmem: allow THP support determination at folio allocation time
Quoted 41 lines · David Hildenbrand (Arm)
Quoted 40 lines · Luiz Capitulino
In order to enable THP support in shmem today, besides the user configuration required, the CPU must support PMD-sized pages. This is the case because of the following
has_transparent_hugepage()usage:-
shmem_parse_one()andshmem_parse_huge(): Check if THP is built-in and if the CPU supports PMD-sized pages-
shmem_init(): Since theCONFIG_TRANSPARENT_HUGEPAGEguard is outside the code block callinghas_transparent_hugepage(), thehas_transparent_hugepage()call is exclusively checking if the CPU supports PMD-sized pagesWhile it's necessary to check if
CONFIG_TRANSPARENT_HUGEPAGEis enabled in all cases, shmem can determine THP size support at folio allocation time. Therefore, drop thehas_transparent_hugepage()usage listed above while keeping theCONFIG_TRANSPARENT_HUGEPAGEchecks.Additionally, we need to check if PMD size order is supported in
shmem_getattr(). Usepgtable_has_pmd_leaves()for that.Reviewed-by Baolin Wang <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>--- mm/shmem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)mm/shmem.c +1
-1@@ -690,7 +690,7 @@ static int shmem_parse_huge(const char *str)else return -EINVAL ; -if (!has_transparent_hugepage () && +if (!IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && huge !=SHMEM_HUGE_NEVER && huge !=SHMEM_HUGE_DENY )return -EINVAL ;
Quoted 8 lines
mm/shmem.c static int shmem_getattr(struct mnt_idmap *idmap, · line 1526
Quoted 4 lines
mm/shmem.c +0
-0@@ -1524,6 +1524,8 @@ static int shmem_getattr(struct mnt_idmap *idmap,generic_fillattr (idmap, request_mask, inode, stat); orders =shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 );I'm curious: why is that not handled inside
shmem_huge_global_enabled()? If PMD order is impossible (well, okay, it is possible, but we simply cannot map these things through PMDs), I would expect that we never list them as "enabled".
Yes, you're right. What about renaming current shmem_huge_global_enabled() to __shmem_huge_global_enabled() and then having:
static unsigned int shmem_huge_global_enabled(struct inode *inode, pgoff_t index,
loff_t write_end, bool shmem_huge_force, struct vm_area_struct *vma, vm_flags_t vm_flags)
{
unsigned int orders;
orders = __shmem_huge_global_enabled(inode, index, write_end,
shmem_huge_force, vma, vm_flags);
if (!pgtable_has_pmd_leaves())
orders &= ~BIT(PMD_ORDER);
return orders;
}Would this be acceptable?
Quoted 5 lines
(while shmem could allocate PMD folios, it would have to map them always through PTEs. I think this would be possible through some changes, but we can defer that to some future work).
Baolin Wang
reviewerRe: [PATCH v8 07/14] mm: shmem: allow THP support determination at folio allocation time
Quoted 65 lines · Luiz Capitulino
Quoted 38 lines · David Hildenbrand (Arm)
Quoted 37 lines · Luiz Capitulino
In order to enable THP support in shmem today, besides the user configuration required, the CPU must support PMD-sized pages. This is the case because of the following
has_transparent_hugepage()usage:-
shmem_parse_one()andshmem_parse_huge(): Check if THP is built-in and if the CPU supports PMD-sized pages-
shmem_init(): Since theCONFIG_TRANSPARENT_HUGEPAGEguard is outside the code block callinghas_transparent_hugepage(), thehas_transparent_hugepage()call is exclusively checking if the CPU supports PMD-sized pagesWhile it's necessary to check if
CONFIG_TRANSPARENT_HUGEPAGEis enabled in all cases, shmem can determine THP size support at folio allocation time. Therefore, drop thehas_transparent_hugepage()usage listed above while keeping theCONFIG_TRANSPARENT_HUGEPAGEchecks.Additionally, we need to check if PMD size order is supported in
shmem_getattr(). Usepgtable_has_pmd_leaves()for that.Reviewed-by Baolin Wang <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>---
mm/shmem.c| 9 +++++----1 file changed, 5 insertions(+), 4 deletions(-)mm/shmem.c +0
-0@@ -690,7 +690,7 @@ static int shmem_parse_huge(const char *str)else
return-EINVAL;
- if (!has_transparent_hugepage() &&
+ if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && huge !=SHMEM_HUGE_NEVER&& huge !=SHMEM_HUGE_DENY)Quoted 8 lines
mm/shmem.c static int shmem_getattr(struct mnt_idmap *idmap, · line 1525
Quoted 4 lines
return
-EINVAL;mm/shmem.c +0
-0@@ -1524,6 +1524,8 @@ static int shmem_getattr(struct mnt_idmap *idmap, generic_fillattr(idmap, request_mask, inode, stat); orders = shmem_huge_global_enabled(inode, 0, 0, false, NULL, 0);I'm curious: why is that not handled inside
shmem_huge_global_enabled()? If PMD order is impossible (well, okay, it is possible, but we simply cannot map these things through PMDs), I would expect that we never list them as "enabled".Yes, you're right. What about renaming current
shmem_huge_global_enabled()to__shmem_huge_global_enabled()and then having:static unsigned int shmem_huge_global_enabled(struct inode *inode,
pgoff_tindex,
loff_twrite_end, boolshmem_huge_force, structvm_area_struct*vma,
vm_flags_tvm_flags)
{
unsigned int orders;orders =
__shmem_huge_global_enabled(inode, index, write_end, shmem_huge_force, vma, vm_flags); if (!pgtable_has_pmd_leaves())
orders &= ~BIT(PMD_ORDER);
Quoted 4 lines
return orders;
}Would this be acceptable?
Not a fan of re-adding the wrapper. I think you could refer to the changes to shmem_allowable_huge_orders() in patch 14 and filter out the 'disabled_orders' in shmem_huge_global_enabled() directly.
Re: [PATCH v8 07/14] mm: shmem: allow THP support determination at folio allocation time
Quoted 68 lines · Baolin Wang
Quoted 65 lines · Luiz Capitulino
Quoted 38 lines · David Hildenbrand (Arm)
Quoted 37 lines · Luiz Capitulino
In order to enable THP support in shmem today, besides the user configuration required, the CPU must support PMD-sized pages. This is the case because of the following
has_transparent_hugepage()usage:-
shmem_parse_one()andshmem_parse_huge(): Check if THP is built-in and if the CPU supports PMD-sized pages-
shmem_init(): Since theCONFIG_TRANSPARENT_HUGEPAGEguard is outside the code block callinghas_transparent_hugepage(), thehas_transparent_hugepage()call is exclusively checking if the CPU supports PMD-sized pagesWhile it's necessary to check if
CONFIG_TRANSPARENT_HUGEPAGEis enabled in all cases, shmem can determine THP size support at folio allocation time. Therefore, drop thehas_transparent_hugepage()usage listed above while keeping theCONFIG_TRANSPARENT_HUGEPAGEchecks.Additionally, we need to check if PMD size order is supported in
shmem_getattr(). Usepgtable_has_pmd_leaves()for that.Reviewed-by Baolin Wang <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>--- mm/shmem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)mm/shmem.c +1
-1@@ -690,7 +690,7 @@ static int shmem_parse_huge(const char *str)else return -EINVAL ; -if (!has_transparent_hugepage () && +if (!IS_ENABLED (CONFIG_TRANSPARENT_HUGEPAGE ) && huge !=SHMEM_HUGE_NEVER && huge !=SHMEM_HUGE_DENY )Quoted 8 lines
mm/shmem.c static int shmem_getattr(struct mnt_idmap *idmap, · line 1525
Quoted 4 lines
mm/shmem.c +0
-0return -EINVAL ;@@ -1524,6 +1524,8 @@ static int shmem_getattr(struct mnt_idmap *idmap,generic_fillattr (idmap, request_mask, inode, stat); orders =shmem_huge_global_enabled (inode,0 ,0 , false,NULL ,0 );I'm curious: why is that not handled inside
shmem_huge_global_enabled()? If PMD order is impossible (well, okay, it is possible, but we simply cannot map these things through PMDs), I would expect that we never list them as "enabled".Yes, you're right. What about renaming current
shmem_huge_global_enabled()to__shmem_huge_global_enabled()and then having:static unsigned int shmem_huge_global_enabled(struct inode *inode,
pgoff_tindex,
loff_twrite_end, boolshmem_huge_force, structvm_area_struct*vma,
vm_flags_tvm_flags){ unsigned int orders; orders = __shmem_huge_global_enabled(inode, index, write_end, shmem_huge_force, vma, vm_flags); if (!pgtable_has_pmd_leaves()) orders &= ~BIT(PMD_ORDER);
Quoted 6 lines
Quoted 4 lines
return orders; }Would this be acceptable?
Not a fan of re-adding the wrapper. I think you could refer to the changes to
shmem_allowable_huge_orders()in patch 14 and filter out the 'disabled_orders' inshmem_huge_global_enabled()directly.
OK, I'll look into doing this.
PATCH v8 8/14 s390: move has_transparent_hugepage() out of THP guard
In reply to Luiz CapitulinoA future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the has_transparent_hugepage() implementation but will be orthogonal to THP and therefore must work when CONFIG_TRANSPARENT_HUGEPAGE=n.
Move its definition out of the THP guard.
--- arch/s390/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/include/asm/pgtable.h +1 -1
@@ -1814,13 +1814,13 @@ static inline int pmd_trans_huge(pmd_t pmd) {return pmd_leaf (pmd); } +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #define has_transparent_hugepage has_transparent_hugepagestatic inline int has_transparent_hugepage (void ) {return cpu_has_edat1 () ?1 :0 ; } -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #ifdef CONFIG_PAGE_TABLE_CHECK static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte)
Signature · 1 line
2.55.0
Re: [PATCH v8 08/14] s390: move has_transparent_hugepage() out of THP guard
Quoted 5 lines · Luiz Capitulino
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.
Quoted 7 lines
Move its definition out of the THP guard.
Signed-off-by Luiz Capitulino <[email protected]>--- arch/s390/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Signature · 2 lines
Best Regards, Yan, Zi
Re: [PATCH v8 08/14] s390: move has_transparent_hugepage() out of THP guard
In reply to Luiz CapitulinoQuoted 8 lines · Luiz Capitulino
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.Move its definition out of the THP guard.
Signed-off-by Luiz Capitulino <[email protected]>
Signature · 3 lines
Cheers, David
PATCH v8 9/14 powerpc: move has_transparent_hugepage() out of THP guard
In reply to Luiz CapitulinoA future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the has_transparent_hugepage() implementation but will be orthogonal to THP and therefore must work when CONFIG_TRANSPARENT_HUGEPAGE=n.
Move its definition out of the THP guard.
--- 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 | 18 +++++++++--------- arch/powerpc/include/asm/book3s/64/radix.h | 14 +++++++------- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-)
arch/powerpc/include/asm/book3s/64/hash-4k.h +1 -1
@@ -165,9 +165,9 @@ 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 );#endif +extern int hash__has_transparent_hugepage (void );#endif /* !__ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
arch/powerpc/include/asm/book3s/64/hash-64k.h +1 -1
@@ -278,9 +278,9 @@ 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 );#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +extern int hash__has_transparent_hugepage (void );#endif /* __ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
arch/powerpc/include/asm/book3s/64/pgtable.h +9 -9
@@ -1114,15 +1114,6 @@ 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 ) -{ -if (radix_enabled ()) -return radix__has_transparent_hugepage (); -return hash__has_transparent_hugepage (); -} -#define has_transparent_hugepage has_transparent_hugepage -static inline int has_transparent_pud_hugepage (void ) {if (radix_enabled ())
@@ -1434,6 +1425,15 @@ static inline bool arch_needs_pgtable_deposit(void)#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +extern int hash__has_transparent_hugepage (void ); +static inline int has_transparent_hugepage (void ) +{ +if (radix_enabled ()) +return radix__has_transparent_hugepage (); +return hash__has_transparent_hugepage (); +} +#define has_transparent_hugepage has_transparent_hugepage +#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTIONpte_t ptep_modify_prot_start (struct vm_area_struct *,unsigned long ,pte_t *); void ptep_modify_prot_commit(struct vm_area_struct *, unsigned long,
arch/powerpc/include/asm/book3s/64/radix.h +7 -7
@@ -298,22 +298,22 @@ 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__has_transparent_pud_hugepage (void ) { -/* For radix 2M at PMD level means thp */ -if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT ) +/* For radix 1G at PUD level means pud hugepage support */ +if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT )return 1 ;return 0 ; } +#endif -static inline int radix__has_transparent_pud_hugepage (void ) +static inline int radix__has_transparent_hugepage (void ) { -/* For radix 1G at PUD level means pud hugepage support */ -if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT ) +/* For radix 2M at PMD level means thp */ +if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT )return 1 ;return 0 ; } -#endif struct vmem_altmap ;struct dev_pagemap ;
arch/powerpc/mm/book3s64/hash_pgtable.c +2 -2
@@ -391,6 +391,8 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, return old_pmd; } +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +int hash__has_transparent_hugepage (void ) {
@@ -422,8 +424,6 @@ int hash__has_transparent_hugepage(void) }EXPORT_SYMBOL_GPL (hash__has_transparent_hugepage); -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -#ifdef CONFIG_STRICT_KERNEL_RWX struct change_memory_parms {
Signature · 1 line
2.55.0
David Hildenbrand (Arm)
maintainerRe: [PATCH v8 09/14] powerpc: move has_transparent_hugepage() out of THP guard
Quoted 36 lines · Luiz Capitulino
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.Move its definition out of the THP guard.
Signed-off-by Luiz Capitulino <[email protected]>--- 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 | 18 +++++++++--------- arch/powerpc/include/asm/book3s/64/radix.h | 14 +++++++------- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-)arch/powerpc/include/asm/book3s/64/hash-4k.h +1
-1@@ -165,9 +165,9 @@ 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 );#endif +extern int hash__has_transparent_hugepage (void );#endif /* !__ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-0
arch/powerpc/include/asm/book3s/64/hash-64k.h extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, · line 281
Quoted 4 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-1@@ -278,9 +278,9 @@ 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 );
Without some of these helpers in place, I assume actually using PMD leafs without THP would require some more work. (which is not the goal of this series, just asking).
I do wonder whether the architecture should instead simply say "not supported" if !CONFIG_TRANSPARENT_HUGEPAGE?
That should still enable your series: using mTHP without PMD support.
[...]
Quoted 13 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +4
-3-static inline int radix__has_transparent_hugepage (void ) +static inline int radix__has_transparent_pud_hugepage (void ) { -/* For radix 2M at PMD level means thp */ -if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT ) +/* For radix 1G at PUD level means pud hugepage support */ +if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT )return 1 ;return 0 ; } +#endif
arch/powerpc/include/asm/book3s/64/hash-64k.h extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
Quoted 10 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +3
-3-static inline int radix__has_transparent_pud_hugepage (void ) +static inline int radix__has_transparent_hugepage (void ) { -/* For radix 1G at PUD level means pud hugepage support */ -if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT ) +/* For radix 2M at PMD level means thp */ +if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT )return 1 ;return 0 ; }
You are swapping both implementations, which might create some unnecessary churn I think.
Signature · 3 lines
Cheers, David
Re: [PATCH v8 09/14] powerpc: move has_transparent_hugepage() out of THP guard
Quoted 31 lines · David Hildenbrand (Arm)
Quoted 30 lines · Luiz Capitulino
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.Move its definition out of the THP guard.
Signed-off-by Luiz Capitulino <[email protected]>--- 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 | 18 +++++++++--------- arch/powerpc/include/asm/book3s/64/radix.h | 14 +++++++------- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-)arch/powerpc/include/asm/book3s/64/hash-4k.h +1
-1@@ -165,9 +165,9 @@ 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 );#endif +extern int hash__has_transparent_hugepage (void );#endif /* !__ASSEMBLER__ */
Quoted 14 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, · line 281
Quoted 10 lines
arch/powerpc/include/asm/book3s/64/hash-4k.h +0
-0#endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-1@@ -278,9 +278,9 @@ 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 );Without some of these helpers in place, I assume actually using PMD leafs without THP would require some more work. (which is not the goal of this series, just asking).
Yes, you're right.
Quoted 4 lines
I do wonder whether the architecture should instead simply say "not supported" if !CONFIG_TRANSPARENT_HUGEPAGE?
That should still enable your series: using mTHP without PMD support.
Yes, it would. However, I think this introduces an inconsistency.
In in its current form, arch_has_pmd_leaves() should always report a hardware capability. This is true even for the default case where arch_has_pmd_leaves() defaults to IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE) in the assumption that archs supporting PMD-sized pages by default will have this config enabled.
Your suggestion will change this and for some archs arch_has_pmd_leaves() may have different behavior depending on the user configuration. Additionally, I intended to decouple the base API implementation from THP.
If you feel strongly about this I can implement your suggestion, but I'd still vote for keeping the API about consistently reporting the hardware capability. Even if the only user is THP code today, new use cases can be added incrementally.
Quoted 16 lines
[...]
Quoted 13 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +4
-3-static inline int radix__has_transparent_hugepage (void ) +static inline int radix__has_transparent_pud_hugepage (void ) { -/* For radix 2M at PMD level means thp */ -if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT ) +/* For radix 1G at PUD level means pud hugepage support */ +if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT )return 1 ;return 0 ; } +#endif
Quoted 13 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h
Quoted 10 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +3
-3-static inline int radix__has_transparent_pud_hugepage (void ) +static inline int radix__has_transparent_hugepage (void ) { -/* For radix 1G at PUD level means pud hugepage support */ -if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT ) +/* For radix 2M at PMD level means thp */ +if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT )return 1 ;return 0 ; }You are swapping both implementations, which might create some unnecessary churn I think.
I suspect this was done by git diff as I just moved the functions, but I'll take a better look.
Christophe Leroy (CS GROUP)
reviewerRe: [PATCH v8 09/14] powerpc: move has_transparent_hugepage() out of THP guard
Hi,
Don't forget <[email protected]> when you address powerpc architecture.
Le 03/10/2026 à 17:44, Luiz Capitulino a écrit :
Quoted 49 lines · David Hildenbrand (Arm)
Quoted 37 lines · Luiz Capitulino
Quoted 36 lines
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.Move its definition out of the THP guard.
Signed-off-by Luiz Capitulino <[email protected]>---
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 | 18 +++++++++--------- arch/powerpc/include/asm/book3s/64/radix.h | 14 +++++++------- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++--5 files changed, 20 insertions(+), 20 deletions(-)arch/powerpc/include/asm/book3s/64/hash-4k.h +1
-1@@ -165,9 +165,9 @@ 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 ); #endif +extern int hash__has_transparent_hugepage (void ); #endif /* !__ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-0@@ -278,9 +278,9 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,Quoted 8 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h extern void · line 282
Quoted 4 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-1extern 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 );Without some of these helpers in place, I assume actually using PMD leafs without THP would require some more work. (which is not the goal of this series, just asking).
Quoted 8 lines
Yes, you're right.
Quoted 4 lines
I do wonder whether the architecture should instead simply say "not supported" if !CONFIG_TRANSPARENT_HUGEPAGE?
That should still enable your series: using mTHP without PMD support.
Yes, it would. However, I think this introduces an inconsistency.
powerpc has two types of MMU (HASH and RADIX) with different page layout. MMU type is selected at boottime based on the capabilities of the CPU. For transparent page you have:
static inline int has_transparent_hugepage(void)
{
if (radix_enabled())
return radix__has_transparent_hugepage();
return hash__has_transparent_hugepage();
}Quoted 49 lines
In in its current form,
arch_has_pmd_leaves()should always report a hardware capability. This is true even for the default case wherearch_has_pmd_leaves()defaults toIS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)in the assumption that archs supporting PMD-sized pages by default will have this config enabled.Your suggestion will change this and for some archs
arch_has_pmd_leaves()may have different behavior depending on the user configuration. Additionally, I intended to decouple the base API implementation from THP.If you feel strongly about this I can implement your suggestion, but I'd still vote for keeping the API about consistently reporting the hardware capability. Even if the only user is THP code today, new use cases can be added incrementally.
Quoted 19 lines
[...]
Quoted 16 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +1
-1-static inline int radix__has_transparent_hugepage (void ) +static inline int radix__has_transparent_pud_hugepage (void ){
- /* For radix 2M at PMD level means thp */
- if (mmu_psize_defs[MMU_PAGE_2M].shift ==PMD_SHIFT) + /* For radix 1G at PUD level means pud hugepage support */ + if (mmu_psize_defs[MMU_PAGE_1G].shift ==PUD_SHIFT) return 1;
return 0;
}arch/powerpc/include/asm/book3s/64/hash-64k.h +2
-1+#endif -static inline int radix__has_transparent_pud_hugepage (void ) +static inline int radix__has_transparent_hugepage (void ){
- /* For radix 1G at PUD level means pud hugepage support */ - if (mmu_psize_defs[MMU_PAGE_1G].shift ==PUD_SHIFT)Quoted 8 lines
Quoted 5 lines
+ /* For radix 2M at PMD level means thp */ + if (mmu_psize_defs[MMU_PAGE_2M].shift ==
PMD_SHIFT) return 1;
return 0;
}You are swapping both implementations, which might create some unnecessary churn I think.
I suspect this was done by git diff as I just moved the functions, but I'll take a better look.
Re: [PATCH v8 09/14] powerpc: move has_transparent_hugepage() out of THP guard
Quoted 3 lines · Christophe Leroy (CS GROUP)
Hi,
Don't forget <[email protected]> when you address powerpc architecture.
Will do.
Quoted 58 lines · Luiz Capitulino
Quoted 47 lines · David Hildenbrand (Arm)
Quoted 35 lines · Luiz Capitulino
Quoted 34 lines
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.Move its definition out of the THP guard.
Signed-off-by Luiz Capitulino <[email protected]>--- 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 | 18 +++++++++--------- arch/powerpc/include/asm/book3s/64/radix.h | 14 +++++++------- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-)arch/powerpc/include/asm/book3s/64/hash-4k.h +1
-1@@ -165,9 +165,9 @@ 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 );#endif +extern int hash__has_transparent_hugepage (void );#endif /* !__ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-0@@ -278,9 +278,9 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,Quoted 8 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, · line 281
Quoted 4 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-1extern 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 );Without some of these helpers in place, I assume actually using PMD leafs without THP would require some more work. (which is not the goal of this series, just asking).
Quoted 8 lines
Yes, you're right.
Quoted 4 lines
I do wonder whether the architecture should instead simply say "not supported" if !CONFIG_TRANSPARENT_HUGEPAGE?
That should still enable your series: using mTHP without PMD support.
Yes, it would. However, I think this introduces an inconsistency.
Quoted 8 lines
powerpc has two types of MMU (HASH and RADIX) with different page layout. MMU type is selected at boottime based on the capabilities of the CPU. For transparent page you have:
static inline int
has_transparent_hugepage(void){ if (radix_enabled()) return radix__has_transparent_hugepage(); return hash__has_transparent_hugepage(); }
Right and, unless I'm misunderstanding your comment, this supports my position that the new arch_has_pmd_leaves() API is all about reporting a hardware capability and not tied to THP support.
Quoted 51 lines
Quoted 50 lines
In in its current form,
arch_has_pmd_leaves()should always report a hardware capability. This is true even for the default case wherearch_has_pmd_leaves()defaults toIS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)in the assumption that archs supporting PMD-sized pages by default will have this config enabled.Your suggestion will change this and for some archs
arch_has_pmd_leaves()may have different behavior depending on the user configuration. Additionally, I intended to decouple the base API implementation from THP.If you feel strongly about this I can implement your suggestion, but I'd still vote for keeping the API about consistently reporting the hardware capability. Even if the only user is THP code today, new use cases can be added incrementally.
Quoted 19 lines
[...]
Quoted 16 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +5
-6-static inline int radix__has_transparent_hugepage (void ) +static inline int radix__has_transparent_pud_hugepage (void ) { -/* For radix 2M at PMD level means thp */ -if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT ) +/* For radix 1G at PUD level means pud hugepage support */ +if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT )return 1 ;return 0 ; } +#endif -static inline int radix__has_transparent_pud_hugepage (void ) +static inline int radix__has_transparent_hugepage (void ) { -/* For radix 1G at PUD level means pud hugepage support */ -if (mmu_psize_defs[MMU_PAGE_1G ].shift ==PUD_SHIFT )Quoted 8 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h
Quoted 5 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +2
-0+/* For radix 2M at PMD level means thp */ +if (mmu_psize_defs[MMU_PAGE_2M ].shift ==PMD_SHIFT )return 1 ;return 0 ; }You are swapping both implementations, which might create some unnecessary churn I think.
I suspect this was done by git diff as I just moved the functions, but I'll take a better look.
Christophe Leroy (CS GROUP)
reviewerRe: [PATCH v8 09/14] powerpc: move has_transparent_hugepage() out of THP guard
Le 05/10/2026 à 22:40, Luiz Capitulino a écrit :
Quoted 79 lines · Christophe Leroy (CS GROUP)
Quoted 3 lines
Hi,
Don't forget <[email protected]> when you address powerpc architecture.
Will do.
Quoted 61 lines · Luiz Capitulino
Quoted 50 lines · David Hildenbrand (Arm)
Quoted 38 lines · Luiz Capitulino
Quoted 37 lines
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.Move its definition out of the THP guard.
Signed-off-by Luiz Capitulino <[email protected]>---
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 | 18 +++++++++--------- arch/powerpc/include/asm/book3s/64/radix.h | 14 +++++++------- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-)arch/powerpc/include/asm/book3s/64/hash-4k.h +1
-1@@ -165,9 +165,9 @@ 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 ); #endif +extern int hash__has_transparent_hugepage (void ); #endif /* !__ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-0@@ -278,9 +278,9 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,Quoted 8 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h extern void · line 282
Quoted 4 lines
arch/powerpc/include/asm/book3s/64/hash-64k.h +0
-1extern 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 );Without some of these helpers in place, I assume actually using PMD leafs without THP would require some more work. (which is not the goal of this series, just asking).
Quoted 8 lines
Yes, you're right.
Quoted 4 lines
I do wonder whether the architecture should instead simply say "not supported" if !CONFIG_TRANSPARENT_HUGEPAGE?
That should still enable your series: using mTHP without PMD support.
Yes, it would. However, I think this introduces an inconsistency.
Quoted 8 lines
powerpc has two types of MMU (HASH and RADIX) with different page layout. MMU type is selected at boottime based on the capabilities of the CPU. For transparent page you have:
static inline int
has_transparent_hugepage(void){
if (radix_enabled())
returnradix__has_transparent_hugepage(); returnhash__has_transparent_hugepage(); }
Quoted 3 lines
Right and, unless I'm misunderstanding your comment, this supports my position that the new
arch_has_pmd_leaves()API is all about reporting a hardware capability and not tied to THP support.
Yes my comment was in reaction of comment below, I wanted to say that CONFIG_TRANSPARENT_HUGEPAGE is not always enough to tell if a powerpc actually has transparent hugepages or not.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
I do wonder whether the architecture should instead simply say "not supported"
if !CONFIG_TRANSPARENT_HUGEPAGE?That should still enable your series: using mTHP without PMD support.
PATCH v8 10/14 mips: move has_transparent_hugepage() out of THP guard
In reply to Luiz CapitulinoA future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the has_transparent_hugepage() implementation but will be orthogonal to THP and therefore must work when CONFIG_TRANSPARENT_HUGEPAGE=n.
This commit moves has_transparent_hugepage() definition to arch/mips/mm/pgtable.c under CONFIG_CPU_SUPPORTS_HUGEPAGES guard in order to ensure that it's only used in CPUs that support the register operations performed.
--- arch/mips/include/asm/pgtable.h | 6 +++--- arch/mips/mm/pgtable.c | 25 +++++++++++++++++++++++++ arch/mips/mm/tlb-r4k.c | 22 ---------------------- 3 files changed, 28 insertions(+), 25 deletions(-)
arch/mips/include/asm/pgtable.h +3 -3
@@ -615,9 +615,6 @@ 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 ); -static inline int pmd_trans_huge (pmd_t pmd) {return !!(pmd_val (pmd) & _PAGE_HUGE);
@@ -743,6 +740,9 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +#define has_transparent_hugepage has_transparent_hugepage +extern int has_transparent_hugepage (void ); +#ifdef _PAGE_HUGE#define pmd_leaf (pmd) ((pmd_val(pmd) & _PAGE_HUGE) != 0)#define pud_leaf (pud) ((pud_val(pud) & _PAGE_HUGE) != 0)
arch/mips/mm/pgtable.c +25 -0
@@ -23,3 +23,28 @@ pgd_t *pgd_alloc(struct mm_struct *mm)return ret; }EXPORT_SYMBOL_GPL (pgd_alloc); + +#ifdef CONFIG_CPU_SUPPORTS_HUGEPAGES +int has_transparent_hugepage (void ) +{ +static unsigned int mask =-1 ; + +if (mask ==-1 ) {/* first call comes during __init */ +unsigned long flags; + +local_irq_save (flags); +write_c0_pagemask (PM_HUGE_MASK ); +back_to_back_c0_hazard (); + mask =read_c0_pagemask (); +write_c0_pagemask (PM_DEFAULT_MASK ); +local_irq_restore (flags); + } +return mask ==PM_HUGE_MASK ; +} +#else +int has_transparent_hugepage (void ) +{ +return 0 ; +} +#endif +EXPORT_SYMBOL (has_transparent_hugepage);
arch/mips/mm/tlb-r4k.c +0 -22
@@ -432,28 +432,6 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,#endif } -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - -int has_transparent_hugepage (void ) -{ -static unsigned int mask =-1 ; - -if (mask ==-1 ) {/* first call comes during __init */ -unsigned long flags; - -local_irq_save (flags); -write_c0_pagemask (PM_HUGE_MASK ); -back_to_back_c0_hazard (); - mask =read_c0_pagemask (); -write_c0_pagemask (PM_DEFAULT_MASK ); -local_irq_restore (flags); - } -return mask ==PM_HUGE_MASK ; -} -EXPORT_SYMBOL (has_transparent_hugepage); - -#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -/* * Used for loading TLB entries before trap_init() has started, when we * don't actually want to add a wired entry which remains throughout the
Signature · 1 line
2.55.0
David Hildenbrand (Arm)
maintainerRe: [PATCH v8 10/14] mips: move has_transparent_hugepage() out of THP guard
Quoted 4 lines · Luiz Capitulino
A future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the
has_transparent_hugepage()implementation but will be orthogonal to THP and therefore must work whenCONFIG_TRANSPARENT_HUGEPAGE=n.
Same thought as for the previous commit: it would be fine for now for the architecture to simply say "not supported" without CONFIG_TRANSPARENT_HUGEPAGE, right?
Signature · 3 lines
Cheers, David
PATCH v8 11/14 x86: move has_transparent_hugepage() out of THP guard
In reply to Luiz CapitulinoA future commit will introduce a kernel API to allow for checking if the CPU supports PMD-sized pages. This API will be based on the has_transparent_hugepage() implementation but will be orthogonal to THP and therefore must work when CONFIG_TRANSPARENT_HUGEPAGE=n.
Move its definition out of the THP guard.
--- arch/x86/include/asm/pgtable.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/x86/include/asm/pgtable.h +6 -6
@@ -306,12 +306,6 @@ static inline int pud_trans_huge(pud_t pud) }#endif -#define has_transparent_hugepage has_transparent_hugepage -static inline int has_transparent_hugepage (void ) -{ -return boot_cpu_has (X86_FEATURE_PSE ); -} -#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP static inline bool pmd_special (pmd_t pmd) {
@@ -337,6 +331,12 @@ static inline pud_t pud_mkspecial(pud_t pud)#endif /* CONFIG_ARCH_SUPPORTS_PUD_PFNMAP */ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +#define has_transparent_hugepage has_transparent_hugepage +static inline int has_transparent_hugepage (void ) +{ +return boot_cpu_has (X86_FEATURE_PSE ); +} +static inline pte_t pte_set_flags (pte_t pte,pteval_t set) {pteval_t v =native_pte_val (pte);
Signature · 1 line
2.55.0
PATCH v8 12/14 treewide: introduce arch_has_pmd_leaves()
In reply to Luiz CapitulinoNow 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 pgtable_leaf_support_init(). The remaining exception is hugepage_init() which will be converted in a future commit.
--- arch/mips/include/asm/pgtable.h | 4 ++-- arch/mips/mm/pgtable.c | 6 +++--- 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, 23 insertions(+), 23 deletions(-)
arch/mips/include/asm/pgtable.h +2 -2
@@ -740,8 +740,8 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -#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 );#ifdef _PAGE_HUGE#define pmd_leaf (pmd) ((pmd_val(pmd) & _PAGE_HUGE) != 0)
arch/mips/mm/pgtable.c +3 -3
@@ -25,7 +25,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)EXPORT_SYMBOL_GPL (pgd_alloc);#ifdef CONFIG_CPU_SUPPORTS_HUGEPAGES -int has_transparent_hugepage (void ) +int arch_has_pmd_leaves (void ) {static unsigned int mask =-1 ;
@@ -42,9 +42,9 @@ int has_transparent_hugepage(void) return mask == PM_HUGE_MASK; }#else -int has_transparent_hugepage (void ) +int arch_has_pmd_leaves (void ) {return 0 ; }#endif -EXPORT_SYMBOL (has_transparent_hugepage); +EXPORT_SYMBOL (arch_has_pmd_leaves);
arch/powerpc/include/asm/book3s/64/hash-4k.h +1 -1
@@ -167,7 +167,7 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp);#endif -extern int hash__has_transparent_hugepage (void ); +extern int hash__arch_has_pmd_leaves (void );#endif /* !__ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
arch/powerpc/include/asm/book3s/64/hash-64k.h +1 -1
@@ -280,7 +280,7 @@ extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp);#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -extern int hash__has_transparent_hugepage (void ); +extern int hash__arch_has_pmd_leaves (void );#endif /* __ASSEMBLER__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
arch/powerpc/include/asm/book3s/64/pgtable.h +5 -5
@@ -1425,14 +1425,14 @@ static inline bool arch_needs_pgtable_deposit(void)#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -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#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTIONpte_t ptep_modify_prot_start (struct vm_area_struct *,unsigned long ,pte_t *);
arch/powerpc/include/asm/book3s/64/radix.h +1 -1
@@ -307,7 +307,7 @@ static inline int radix__has_transparent_pud_hugepage(void) }#endif -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 )
arch/powerpc/mm/book3s64/hash_pgtable.c +2 -2
@@ -393,7 +393,7 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -int hash__has_transparent_hugepage (void ) +int hash__arch_has_pmd_leaves (void ) {if (!mmu_has_feature (MMU_FTR_16M_PAGE ))
@@ -422,7 +422,7 @@ int hash__has_transparent_hugepage(void)return 1 ; } -EXPORT_SYMBOL_GPL (hash__has_transparent_hugepage); +EXPORT_SYMBOL_GPL (hash__arch_has_pmd_leaves);#ifdef CONFIG_STRICT_KERNEL_RWX
arch/s390/include/asm/pgtable.h +2 -2
@@ -1816,8 +1816,8 @@ static inline int pmd_trans_huge(pmd_t pmd) }#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -#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 ; }
arch/x86/include/asm/pgtable.h +2 -2
@@ -331,8 +331,8 @@ static inline pud_t pud_mkspecial(pud_t pud)#endif /* CONFIG_ARCH_SUPPORTS_PUD_PFNMAP */ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -#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 ); }
include/linux/pgtable.h +2 -2
@@ -2359,8 +2359,8 @@ static inline void __init pgtable_leaf_support_init(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 #ifndef has_transparent_pud_hugepage
mm/huge_memory.c +1 -1
@@ -1091,7 +1091,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 ; }
mm/memory.c +1 -1
@@ -169,7 +169,7 @@ EXPORT_SYMBOL(__arch_has_pmd_leaves_key);void __init pgtable_leaf_support_init (void ) { -if (!has_transparent_hugepage ()) +if (!arch_has_pmd_leaves ())static_branch_disable (&__arch_has_pmd_leaves_key); }
Signature · 1 line
2.55.0
Re: [PATCH v8 12/14] treewide: introduce arch_has_pmd_leaves()
Quoted 17 lines · Luiz Capitulino
Now that all the
has_transparent_hugepage()callers have been converted topgtable_has_pmd_leaves(), this commit does two things:1. Rename
has_transparent_hugepage()arch implementations toarch_has_pmd_leaves(), since that's what the helper checks for2. Introduce the default implementation of
arch_has_pmd_leaves()asIS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE). This means that if the arch doesn't implementarch_has_pmd_leaves()we default to checkingCONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGEas a way to determine if PMD-sized pages are supportedNote that
arch_has_pmd_leaves()is supposed to be called only bypgtable_leaf_support_init(). The remaining exception ishugepage_init()which will be converted in a future commit.Signed-off-by Luiz Capitulino <[email protected]>
Quoted 15 lines
--- arch/mips/include/asm/pgtable.h | 4 ++-- arch/mips/mm/pgtable.c | 6 +++--- 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, 23 insertions(+), 23 deletions(-)
Signature · 2 lines
Best Regards, Yan, Zi
PATCH v8 13/14 mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves()
In reply to Luiz CapitulinoDespite its name, thp_disabled_by_hw() just checks whether the architecture supports PMD-sized pages. It returns true when TRANSPARENT_HUGEPAGE_UNSUPPORTED is set in transparent_hugepage_flags, this only occurs if the architecture implements arch_has_pmd_leaves() and that function returns false.
Since pgtable_has_pmd_leaves() provides the same semantics, use it instead.
--- include/linux/huge_mm.h | 7 ------- mm/huge_memory.c | 6 ++---- mm/memory.c | 2 +- mm/shmem.c | 2 +- 4 files changed, 4 insertions(+), 13 deletions(-)
include/linux/huge_mm.h +0 -7
@@ -47,7 +47,6 @@ vm_fault_t vmf_insert_folio_pud(struct vm_fault *vmf, struct folio *folio, bool write);enum transparent_hugepage_flag { -TRANSPARENT_HUGEPAGE_UNSUPPORTED ,TRANSPARENT_HUGEPAGE_FLAG ,TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG ,TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG ,
@@ -383,12 +382,6 @@ static inline bool vma_thp_disabled(struct vm_area_struct *vma,return mm_flags_test (MMF_DISABLE_THP_EXCEPT_ADVISED , vma->vm_mm); } -static inline bool thp_disabled_by_hw (void ) -{ -/* If the hardware/firmware marked hugepage support disabled. */ -return transparent_hugepage_flags & (1 <<TRANSPARENT_HUGEPAGE_UNSUPPORTED ); -} -unsigned long thp_get_unmapped_area (struct file *filp,unsigned long addr,unsigned long len,unsigned long pgoff,unsigned long flags); unsigned long thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,
mm/huge_memory.c +2 -4
@@ -196,7 +196,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,if (!vma->vm_mm)/* vdso */ return 0 ; -if (thp_disabled_by_hw () ||vma_thp_disabled (vma, vm_flags, forced_collapse)) +if (!pgtable_has_pmd_leaves () ||vma_thp_disabled (vma, vm_flags, forced_collapse))return 0 ;/* khugepaged doesn't collapse DAX vma, but page fault is fine. */
@@ -1091,10 +1091,8 @@ static int __init hugepage_init(void)int err;struct kobject *hugepage_kobj; -if (!arch_has_pmd_leaves ()) { - transparent_hugepage_flags =1 <<TRANSPARENT_HUGEPAGE_UNSUPPORTED ; +if (!pgtable_has_pmd_leaves ())return -EINVAL ; - }/* * hugepages can't be allocated by the buddy allocator
mm/memory.c +1 -1
@@ -5694,7 +5694,7 @@ vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *pa* PMD mappings if THPs are disabled. As we already have a THP, * behave as if we are forcing a collapse. */ -if (thp_disabled_by_hw () ||vma_thp_disabled (vma, vma->vm_flags, +if (!pgtable_has_pmd_leaves () ||vma_thp_disabled (vma, vma->vm_flags,/* forced_collapse=*/ true))return ret;
mm/shmem.c +1 -1
@@ -2048,7 +2048,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,vm_flags_t vm_flags = vma ? vma->vm_flags :0 ;unsigned int global_orders; -if (thp_disabled_by_hw () || (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))) +if (!pgtable_has_pmd_leaves () || (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force)))return 0 ; global_orders = shmem_huge_global_enabled(inode, index, write_end,
Signature · 1 line
2.55.0
David Hildenbrand (Arm)
maintainerRe: [PATCH v8 13/14] mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves()
Quoted 9 lines · Luiz Capitulino
Despite its name,
thp_disabled_by_hw()just checks whether the architecture supports PMD-sized pages. It returns true whenTRANSPARENT_HUGEPAGE_UNSUPPORTEDis set intransparent_hugepage_flags, this only occurs if the architecture implementsarch_has_pmd_leaves()and that function returns false.Since
pgtable_has_pmd_leaves()provides the same semantics, use it instead.
Quoted 6 lines
Reviewed-by Lance Yang <[email protected]>Reviewed-by Baolin Wang <[email protected]>Acked-by Zi Yan <[email protected]>Signed-off-by Luiz Capitulino <[email protected]>---
Yes, that's a nice cleanup.
Signature · 3 lines
Cheers, David
PATCH v8 14/14 mm: thp: always enable mTHP support
In reply to Luiz CapitulinoIf PMD-sized pages are not supported on an architecture (ie. the arch implements arch_has_pmd_leaves() and it returns false) then the current code disables all THP, including mTHP.
This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Similarly, this commit implements the following changes for shmem in shmem_allowable_huge_orders():
- Drop the pgtable_has_pmd_leaves() check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPU
--- mm/huge_memory.c | 25 ++++++++++++++++++++----- mm/shmem.c | 14 +++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-)
mm/huge_memory.c +20 -5
@@ -189,6 +189,15 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,else supported_orders =THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + supported_orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + orders &= supported_orders;if (!orders)return 0 ;
@@ -196,7 +205,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,if (!vma->vm_mm)/* vdso */ return 0 ; -if (!pgtable_has_pmd_leaves () ||vma_thp_disabled (vma, vm_flags, forced_collapse)) +if (vma_thp_disabled (vma, vm_flags, forced_collapse))return 0 ;/* khugepaged doesn't collapse DAX vma, but page fault is fine. */
@@ -979,7 +988,7 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)* disable all other sizes. powerpc's PMD_ORDER isn't a compile-time * constant so we have to do this here. */ -if (!anon_orders_configured) +if (!anon_orders_configured &&pgtable_has_pmd_leaves ()) huge_anon_orders_inherit =BIT (PMD_ORDER ); *hugepage_kobj =kobject_create_and_add ("transparent_hugepage" , mm_kobj);
@@ -1001,6 +1010,15 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj) } orders =THP_ORDERS_ALL_ANON |THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + order =highest_order (orders);while (orders) { thpsize =thpsize_create (order, *hugepage_kobj);
@@ -1091,9 +1109,6 @@ static int __init hugepage_init(void)int err;struct kobject *hugepage_kobj; -if (!pgtable_has_pmd_leaves ()) -return -EINVAL ; -/* * hugepages can't be allocated by the buddy allocator */
mm/shmem.c +9 -5
@@ -2046,11 +2046,14 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,unsigned long mask =READ_ONCE (huge_shmem_orders_always);unsigned long within_size_orders =READ_ONCE (huge_shmem_orders_within_size);vm_flags_t vm_flags = vma ? vma->vm_flags :0 ; -unsigned int global_orders; +unsigned int global_orders, disabled_orders =0 ; -if (!pgtable_has_pmd_leaves () || (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))) +if (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))return 0 ; +if (!pgtable_has_pmd_leaves ()) + disabled_orders =BIT (PMD_ORDER ); + global_orders =shmem_huge_global_enabled (inode, index, write_end, shmem_huge_force, vma, vm_flags);/*
@@ -2058,7 +2061,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* sysfs configs. */ if (!vma || !vma_is_anon_shmem (vma) || shmem_huge_force) -return global_orders; +return global_orders & ~disabled_orders;/* * Following the 'deny' semantics of the top level, force the huge
@@ -2072,7 +2075,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* means non-PMD sized THP can not override 'huge' mount option now. */ if (shmem_huge ==SHMEM_HUGE_FORCE ) -return READ_ONCE (huge_shmem_orders_inherit); +return READ_ONCE (huge_shmem_orders_inherit) & ~disabled_orders;/* Allow mTHP that will be fully within i_size. */ mask |=shmem_get_orders_within_size (inode, within_size_orders, index,0 );
@@ -2083,6 +2086,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,if (global_orders >0 ) mask |=READ_ONCE (huge_shmem_orders_inherit); + mask &= ~disabled_orders;return THP_ORDERS_ALL_FILE_DEFAULT & mask; }
@@ -5630,7 +5634,7 @@ void __init shmem_init(void)* Default to setting PMD-sized THP to inherit the global setting and * disable all other multi-size THPs. */ -if (!shmem_orders_configured) +if (!shmem_orders_configured &&pgtable_has_pmd_leaves ()) huge_shmem_orders_inherit =BIT (HPAGE_PMD_ORDER );#endif return ;
Signature · 1 line
2.55.0
Quoted 11 lines · Luiz Capitulino
If PMD-sized pages are not supported on an architecture (ie. the arch implements
arch_has_pmd_leaves()and it returns false) then the current code disables all THP, including mTHP.This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Similarly, this commit implements the following changes for shmem in
shmem_allowable_huge_orders():
Quoted 7 lines
- Drop the
pgtable_has_pmd_leaves()check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPUSigned-off-by Luiz Capitulino <[email protected]>---
LGTM.
Usama Arif
reviewerQuoted 77 lines · On Thu, 17 Sep 2026 21:45:35 -0400 Luiz Capitulino <[email protected]> wrote:
If PMD-sized pages are not supported on an architecture (ie. the arch implements
arch_has_pmd_leaves()and it returns false) then the current code disables all THP, including mTHP.This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Similarly, this commit implements the following changes for shmem in
shmem_allowable_huge_orders():- Drop the
pgtable_has_pmd_leaves()check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPUSigned-off-by Luiz Capitulino <[email protected]>--- mm/huge_memory.c | 25 ++++++++++++++++++++----- mm/shmem.c | 14 +++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-)mm/huge_memory.c +20
-2@@ -189,6 +189,15 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,else supported_orders =THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + supported_orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + orders &= supported_orders;if (!orders)return 0 ;@@ -196,7 +205,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,if (!vma->vm_mm)/* vdso */ return 0 ; -if (!pgtable_has_pmd_leaves () ||vma_thp_disabled (vma, vm_flags, forced_collapse)) +if (vma_thp_disabled (vma, vm_flags, forced_collapse))return 0 ;/* khugepaged doesn't collapse DAX vma, but page fault is fine. */ @@ -979,7 +988,7 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)* disable all other sizes. powerpc's PMD_ORDER isn't a compile-time * constant so we have to do this here. */ -if (!anon_orders_configured) +if (!anon_orders_configured &&pgtable_has_pmd_leaves ()) huge_anon_orders_inherit =BIT (PMD_ORDER ); *hugepage_kobj =kobject_create_and_add ("transparent_hugepage" , mm_kobj);@@ -1001,6 +1010,15 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj) } orders =THP_ORDERS_ALL_ANON |THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + order =highest_order (orders);while (orders) { thpsize =thpsize_create (order, *hugepage_kobj);
mm/huge_memory.c static int __init hugepage_init(void) · line 1096
Quoted 6 lines
mm/huge_memory.c +0
-3@@ -1091,9 +1109,6 @@ static int __init hugepage_init(void)int err;struct kobject *hugepage_kobj; -if (!pgtable_has_pmd_leaves ()) -return -EINVAL ; -
Removing this guard lets start_stop_khugepaged() run on a system without PMD leaves. All mTHP orders default to never, but the global always or madvise flag still makes hugepage_enabled() return true.
That starts an idle khugepaged thread and can unnecessarily raise min_free_kbytes. Could hugepage_enabled() instead test whether an enabled order remains after masking PMD_ORDER when pgtable_has_pmd_leaves() is false?
Quoted 63 lines
mm/huge_memory.c +0
-0/* * hugepages can't be allocated by the buddy allocator */ mm/shmem.c +9
-5@@ -2046,11 +2046,14 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,unsigned long mask =READ_ONCE (huge_shmem_orders_always);unsigned long within_size_orders =READ_ONCE (huge_shmem_orders_within_size);vm_flags_t vm_flags = vma ? vma->vm_flags :0 ; -unsigned int global_orders; +unsigned int global_orders, disabled_orders =0 ; -if (!pgtable_has_pmd_leaves () || (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))) +if (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))return 0 ; +if (!pgtable_has_pmd_leaves ()) + disabled_orders =BIT (PMD_ORDER ); + global_orders =shmem_huge_global_enabled (inode, index, write_end, shmem_huge_force, vma, vm_flags);/* @@ -2058,7 +2061,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* sysfs configs. */ if (!vma || !vma_is_anon_shmem (vma) || shmem_huge_force) -return global_orders; +return global_orders & ~disabled_orders;/* * Following the 'deny' semantics of the top level, force the huge @@ -2072,7 +2075,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* means non-PMD sized THP can not override 'huge' mount option now. */ if (shmem_huge ==SHMEM_HUGE_FORCE ) -return READ_ONCE (huge_shmem_orders_inherit); +return READ_ONCE (huge_shmem_orders_inherit) & ~disabled_orders;/* Allow mTHP that will be fully within i_size. */ mask |=shmem_get_orders_within_size (inode, within_size_orders, index,0 );@@ -2083,6 +2086,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,if (global_orders >0 ) mask |=READ_ONCE (huge_shmem_orders_inherit); + mask &= ~disabled_orders;return THP_ORDERS_ALL_FILE_DEFAULT & mask; }@@ -5630,7 +5634,7 @@ void __init shmem_init(void)* Default to setting PMD-sized THP to inherit the global setting and * disable all other multi-size THPs. */ -if (!shmem_orders_configured) +if (!shmem_orders_configured &&pgtable_has_pmd_leaves ()) huge_shmem_orders_inherit =BIT (HPAGE_PMD_ORDER );#endif return ;Signature · 1 line
2.55.0
Quoted 90 lines · Usama Arif
Quoted 77 lines · On Thu, 17 Sep 2026 21:45:35 -0400 Luiz Capitulino <[email protected]> wrote:
If PMD-sized pages are not supported on an architecture (ie. the arch implements
arch_has_pmd_leaves()and it returns false) then the current code disables all THP, including mTHP.This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Similarly, this commit implements the following changes for shmem in
shmem_allowable_huge_orders():- Drop the
pgtable_has_pmd_leaves()check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPUSigned-off-by Luiz Capitulino <[email protected]>--- mm/huge_memory.c | 25 ++++++++++++++++++++----- mm/shmem.c | 14 +++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-)mm/huge_memory.c +20
-2@@ -189,6 +189,15 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,else supported_orders =THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + supported_orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + orders &= supported_orders;if (!orders)return 0 ;@@ -196,7 +205,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,if (!vma->vm_mm)/* vdso */ return 0 ; -if (!pgtable_has_pmd_leaves () ||vma_thp_disabled (vma, vm_flags, forced_collapse)) +if (vma_thp_disabled (vma, vm_flags, forced_collapse))return 0 ;/* khugepaged doesn't collapse DAX vma, but page fault is fine. */ @@ -979,7 +988,7 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)* disable all other sizes. powerpc's PMD_ORDER isn't a compile-time * constant so we have to do this here. */ -if (!anon_orders_configured) +if (!anon_orders_configured &&pgtable_has_pmd_leaves ()) huge_anon_orders_inherit =BIT (PMD_ORDER ); *hugepage_kobj =kobject_create_and_add ("transparent_hugepage" , mm_kobj);@@ -1001,6 +1010,15 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj) } orders =THP_ORDERS_ALL_ANON |THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + order =highest_order (orders);while (orders) { thpsize =thpsize_create (order, *hugepage_kobj);mm/huge_memory.c static int __init hugepage_init(void) · line 1096
Quoted 6 lines
mm/huge_memory.c +0
-3@@ -1091,9 +1109,6 @@ static int __init hugepage_init(void)int err;struct kobject *hugepage_kobj; -if (!pgtable_has_pmd_leaves ()) -return -EINVAL ; -Removing this guard lets
start_stop_khugepaged()run on a system without PMD leaves. All mTHP orders default to never, but the global always or madvise flag still makeshugepage_enabled()return true.
Quoted 4 lines
That starts an idle khugepaged thread and can unnecessarily raise
min_free_kbytes. Couldhugepage_enabled()instead test whether an enabled order remains after maskingPMD_ORDERwhenpgtable_has_pmd_leaves()is false?
You're right about the issue. Before this series, checking the global configuration was sufficient to determine if THP was "enabled" as PMD leaves would always be available (otherwise THP would be shut down). With this series, we also need to check pgtable_has_pmd_leaves().
I prefer the simple fix below over masking orders in hugepage_enabled():
it's simple and adds the check only in the call site that requires it.
mm/khugepaged.c +1 -1
@@ -453,7 +453,7 @@ static bool hugepage_enabled(void)* Shmem pmd-sized hugepages are also determined by its pmd-size control, * except when the global shmem_huge is set to SHMEM_HUGE_DENY. */ -if (hugepage_global_enabled ()) +if (hugepage_global_enabled () &&pgtable_has_pmd_leaves ())return true;if (anon_hpage_enabled ())return true;
Quoted 65 lines
Quoted 64 lines
mm/huge_memory.c +0
-0/* * hugepages can't be allocated by the buddy allocator */ mm/shmem.c +9
-5@@ -2046,11 +2046,14 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,unsigned long mask =READ_ONCE (huge_shmem_orders_always);unsigned long within_size_orders =READ_ONCE (huge_shmem_orders_within_size);vm_flags_t vm_flags = vma ? vma->vm_flags :0 ; -unsigned int global_orders; +unsigned int global_orders, disabled_orders =0 ; -if (!pgtable_has_pmd_leaves () || (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))) +if (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))return 0 ; +if (!pgtable_has_pmd_leaves ()) + disabled_orders =BIT (PMD_ORDER ); + global_orders =shmem_huge_global_enabled (inode, index, write_end, shmem_huge_force, vma, vm_flags);/* @@ -2058,7 +2061,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* sysfs configs. */ if (!vma || !vma_is_anon_shmem (vma) || shmem_huge_force) -return global_orders; +return global_orders & ~disabled_orders;/* * Following the 'deny' semantics of the top level, force the huge @@ -2072,7 +2075,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* means non-PMD sized THP can not override 'huge' mount option now. */ if (shmem_huge ==SHMEM_HUGE_FORCE ) -return READ_ONCE (huge_shmem_orders_inherit); +return READ_ONCE (huge_shmem_orders_inherit) & ~disabled_orders;/* Allow mTHP that will be fully within i_size. */ mask |=shmem_get_orders_within_size (inode, within_size_orders, index,0 );@@ -2083,6 +2086,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,if (global_orders >0 ) mask |=READ_ONCE (huge_shmem_orders_inherit); + mask &= ~disabled_orders;return THP_ORDERS_ALL_FILE_DEFAULT & mask; }@@ -5630,7 +5634,7 @@ void __init shmem_init(void)* Default to setting PMD-sized THP to inherit the global setting and * disable all other multi-size THPs. */ -if (!shmem_orders_configured) +if (!shmem_orders_configured &&pgtable_has_pmd_leaves ()) huge_shmem_orders_inherit =BIT (HPAGE_PMD_ORDER );#endif return ;Signature · 1 line
2.55.0
Lance Yang
reviewerQuoted 8 lines · Luiz Capitulino
If PMD-sized pages are not supported on an architecture (ie. the arch implements
arch_has_pmd_leaves()and it returns false) then the current code disables all THP, including mTHP.This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Quoted 7 lines
Similarly, this commit implements the following changes for shmem in
shmem_allowable_huge_orders():- Drop the
pgtable_has_pmd_leaves()check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPU
Nit: "and PUD" can go.
David mentioned
"
There is no need to disable PUD-orders, as shmem does not support PUD-orders (unlike DAX). So you can keep it simpler here.
"
in v4
https://lore.kernel.org/all/[email protected]/
Cheers, Lance
Quoted 22 lines · Lance Yang
Quoted 8 lines · Luiz Capitulino
If PMD-sized pages are not supported on an architecture (ie. the arch implements
arch_has_pmd_leaves()and it returns false) then the current code disables all THP, including mTHP.This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Quoted 7 lines
Similarly, this commit implements the following changes for shmem in
shmem_allowable_huge_orders():- Drop the
pgtable_has_pmd_leaves()check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPUNit: "and PUD" can go.
David mentioned
Quoted 8 lines
"
There is no need to disable PUD-orders, as shmem does not support PUD-orders (unlike DAX). So you can keep it simpler here.
"in v4
Yes, I changed the code and didn't update the changelog. Fixed now, thanks Lance.
Quoted 2 lines
Cheers, Lance
Baolin Wang
reviewerQuoted 108 lines · Luiz Capitulino
If PMD-sized pages are not supported on an architecture (ie. the arch implements
arch_has_pmd_leaves()and it returns false) then the current code disables all THP, including mTHP.This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Similarly, this commit implements the following changes for shmem in
shmem_allowable_huge_orders():- Drop the
pgtable_has_pmd_leaves()check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPUSigned-off-by Luiz Capitulino <[email protected]>--- mm/huge_memory.c | 25 ++++++++++++++++++++----- mm/shmem.c | 14 +++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-)mm/huge_memory.c +20
-5@@ -189,6 +189,15 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,else supported_orders =THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + supported_orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + orders &= supported_orders;if (!orders)return 0 ;@@ -196,7 +205,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,if (!vma->vm_mm)/* vdso */ return 0 ; -if (!pgtable_has_pmd_leaves () ||vma_thp_disabled (vma, vm_flags, forced_collapse)) +if (vma_thp_disabled (vma, vm_flags, forced_collapse))return 0 ;/* khugepaged doesn't collapse DAX vma, but page fault is fine. */ @@ -979,7 +988,7 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)* disable all other sizes. powerpc's PMD_ORDER isn't a compile-time * constant so we have to do this here. */ -if (!anon_orders_configured) +if (!anon_orders_configured &&pgtable_has_pmd_leaves ()) huge_anon_orders_inherit =BIT (PMD_ORDER ); *hugepage_kobj =kobject_create_and_add ("transparent_hugepage" , mm_kobj);@@ -1001,6 +1010,15 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj) } orders =THP_ORDERS_ALL_ANON |THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + order =highest_order (orders);while (orders) { thpsize =thpsize_create (order, *hugepage_kobj);@@ -1091,9 +1109,6 @@ static int __init hugepage_init(void)int err;struct kobject *hugepage_kobj; -if (!pgtable_has_pmd_leaves ()) -return -EINVAL ; -/* * hugepages can't be allocated by the buddy allocator */ mm/shmem.c +5
-2@@ -2046,11 +2046,14 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,unsigned long mask =READ_ONCE (huge_shmem_orders_always);unsigned long within_size_orders =READ_ONCE (huge_shmem_orders_within_size);vm_flags_t vm_flags = vma ? vma->vm_flags :0 ; -unsigned int global_orders; +unsigned int global_orders, disabled_orders =0 ; -if (!pgtable_has_pmd_leaves () || (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))) +if (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))return 0 ; +if (!pgtable_has_pmd_leaves ()) + disabled_orders =BIT (PMD_ORDER ); + global_orders =shmem_huge_global_enabled (inode, index, write_end, shmem_huge_force, vma, vm_flags);/*
mm/shmem.c unsigned long shmem_allowable_huge_orders(struct inode *inode, · line 2064
Quoted 5 lines
mm/shmem.c +1
-1@@ -2058,7 +2061,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* sysfs configs. */ if (!vma || !vma_is_anon_shmem (vma) || shmem_huge_force) -return global_orders; +return global_orders & ~disabled_orders;
If you move the 'disabled_orders' filtering logic into shmem_huge_global_enabled(), as I mentioned in patch 8, then this change can be removed.
mm/shmem.c unsigned long shmem_allowable_huge_orders(struct inode *inode, · line 2078
Quoted 8 lines
mm/shmem.c +1
-1/* * Following the 'deny' semantics of the top level, force the huge @@ -2072,7 +2075,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* means non-PMD sized THP can not override 'huge' mount option now. */ if (shmem_huge ==SHMEM_HUGE_FORCE ) -return READ_ONCE (huge_shmem_orders_inherit); +return READ_ONCE (huge_shmem_orders_inherit) & ~disabled_orders;
Since you've already disabled PMD-sized and PUD-sized orders for the 'shmem_enabled' interface in hugepage_init_sysfs(), this change can also be dropped.
mm/shmem.c unsigned long shmem_allowable_huge_orders(struct inode *inode, · line 2089
Quoted 7 lines
mm/shmem.c +1
-0/* Allow mTHP that will be fully within i_size. */ mask |=shmem_get_orders_within_size (inode, within_size_orders, index,0 );@@ -2083,6 +2086,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,if (global_orders >0 ) mask |=READ_ONCE (huge_shmem_orders_inherit); + mask &= ~disabled_orders;
Ditto.
Quoted 2 lines
mm/shmem.c +0
-0return THP_ORDERS_ALL_FILE_DEFAULT & mask; }
Quoted 122 lines · Baolin Wang
Quoted 100 lines · Luiz Capitulino
If PMD-sized pages are not supported on an architecture (ie. the arch implements
arch_has_pmd_leaves()and it returns false) then the current code disables all THP, including mTHP.This commit fixes this by allowing mTHP to be always enabled for all archs. When PMD-sized pages are not supported, its sysfs entry won't be created and their mapping will be disallowed at page-fault time.
Similarly, this commit implements the following changes for shmem in
shmem_allowable_huge_orders():- Drop the
pgtable_has_pmd_leaves()check so that mTHP sizes are considered
- Filter out PMD and PUD orders from allowable orders when PMD-sized pages are not supported by the CPUSigned-off-by Luiz Capitulino <[email protected]>--- mm/huge_memory.c | 25 ++++++++++++++++++++----- mm/shmem.c | 14 +++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-)mm/huge_memory.c +20
-5@@ -189,6 +189,15 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,else supported_orders =THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + supported_orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + orders &= supported_orders;if (!orders)return 0 ;@@ -196,7 +205,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,if (!vma->vm_mm)/* vdso */ return 0 ; -if (!pgtable_has_pmd_leaves () ||vma_thp_disabled (vma, vm_flags, forced_collapse)) +if (vma_thp_disabled (vma, vm_flags, forced_collapse))return 0 ;/* khugepaged doesn't collapse DAX vma, but page fault is fine. */ @@ -979,7 +988,7 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)* disable all other sizes. powerpc's PMD_ORDER isn't a compile-time * constant so we have to do this here. */ -if (!anon_orders_configured) +if (!anon_orders_configured &&pgtable_has_pmd_leaves ()) huge_anon_orders_inherit =BIT (PMD_ORDER ); *hugepage_kobj =kobject_create_and_add ("transparent_hugepage" , mm_kobj);@@ -1001,6 +1010,15 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj) } orders =THP_ORDERS_ALL_ANON |THP_ORDERS_ALL_FILE_DEFAULT ; +if (!pgtable_has_pmd_leaves ()) { +/* +* If the CPU does not support PMD leaves, assume for +* now that it does not support PUD leaves and disable +* both folio orders. +*/ + orders &= ~(BIT (PMD_ORDER ) |BIT (PUD_ORDER )); + } + order =highest_order (orders);while (orders) { thpsize =thpsize_create (order, *hugepage_kobj);@@ -1091,9 +1109,6 @@ static int __init hugepage_init(void)int err;struct kobject *hugepage_kobj; -if (!pgtable_has_pmd_leaves ()) -return -EINVAL ; -/* * hugepages can't be allocated by the buddy allocator */ mm/shmem.c +5
-2@@ -2046,11 +2046,14 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,unsigned long mask =READ_ONCE (huge_shmem_orders_always);unsigned long within_size_orders =READ_ONCE (huge_shmem_orders_within_size);vm_flags_t vm_flags = vma ? vma->vm_flags :0 ; -unsigned int global_orders; +unsigned int global_orders, disabled_orders =0 ; -if (!pgtable_has_pmd_leaves () || (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))) +if (vma &&vma_thp_disabled (vma, vm_flags, shmem_huge_force))return 0 ; +if (!pgtable_has_pmd_leaves ()) + disabled_orders =BIT (PMD_ORDER ); + global_orders =shmem_huge_global_enabled (inode, index, write_end, shmem_huge_force, vma, vm_flags);/* mm/shmem.c unsigned long shmem_allowable_huge_orders(struct inode *inode, · line 2064
Quoted 5 lines
mm/shmem.c +1
-1@@ -2058,7 +2061,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* sysfs configs. */ if (!vma || !vma_is_anon_shmem (vma) || shmem_huge_force) -return global_orders; +return global_orders & ~disabled_orders;If you move the '
disabled_orders' filtering logic intoshmem_huge_global_enabled(), as I mentioned in patch 8, then this change can be removed.mm/shmem.c unsigned long shmem_allowable_huge_orders(struct inode *inode, · line 2078
Quoted 8 lines
mm/shmem.c +1
-1/* * Following the 'deny' semantics of the top level, force the huge @@ -2072,7 +2075,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,* means non-PMD sized THP can not override 'huge' mount option now. */ if (shmem_huge ==SHMEM_HUGE_FORCE ) -return READ_ONCE (huge_shmem_orders_inherit); +return READ_ONCE (huge_shmem_orders_inherit) & ~disabled_orders;Since you've already disabled PMD-sized and PUD-sized orders for the '
shmem_enabled' interface inhugepage_init_sysfs(), this change can also be dropped.
Quoted 8 lines
mm/shmem.c unsigned long shmem_allowable_huge_orders(struct inode *inode, · line 2088
Quoted 6 lines
mm/shmem.c +1
-0/* Allow mTHP that will be fully within i_size. */ mask |=shmem_get_orders_within_size (inode, within_size_orders, index,0 );@@ -2083,6 +2086,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,if (global_orders >0 ) mask |=READ_ONCE (huge_shmem_orders_inherit); + mask &= ~disabled_orders;Ditto.
Yes, I'll look into implementing your suggestions for the next version.
Quoted 4 lines
Quoted 3 lines
mm/shmem.c +0
-0return THP_ORDERS_ALL_FILE_DEFAULT & mask; }
Usama Arif
reviewerQuoted 6 lines · Luiz Capitulino
Introduction
============Today, if an architecture implements
has_transparent_hugepage()and the CPU lacks support for PMD-sized pages, the THP code disables all THP, including mTHP.
Hi Luiz,
Sorry for asking this so late in the series, but which CPUs lack support for PMD sized pages?
Is this series mainly for PowerPC?
Thanks,
Usama
Quoted 172 lines
This happens because the
has_transparent_hugepage()helper is overloaded:
its name implies it checks whether THP is enabled, but on some architectures it actually checks whether the CPU supports PMD-sized pages. In addition, the THP and shmem code have a big switch onhas_transparent_hugepage().This series solves this by decoupling THP availability checking from querying CPU support for PMD-sized pages. THP availability can be checked with
IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE). For querying PMD-sized page support, this series introduces a new helper calledpgtable_has_pmd_leaves(), which is independent of THP, has well defined semantics and can be used in fast paths.Core THP code and shmem can use
pgtable_has_pmd_leaves()to determine PMD-sized THP support at page fault time (or folio allocation time for shmem), leaving THP and shmem always enabled for other THP sizes. For architectures and CPUs that do support PMD-sized pages there's no intended change in behavior.We also convert each user of
has_transparent_hugepage(), and the related helperthp_disabled_by_hw(), toIS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)and/orpgtable_has_pmd_leaves()according to the call site's check semantics. On s390, powerpc, mips and x86 the archhas_transparent_hugepage()implementation is moved out of theCONFIG_TRANSPARENT_HUGEPAGEguard and renamed toarch_has_pmd_leaves().Thanks to David Hildenbrand for suggesting this improvement and for providing initial guidance (all bugs and misconceptions are mine).
This applies to mm-new
93f615a22169("mm/swap, PM: hibernate: atomically replace hibernation pin").Reporting availability of PMD-sized pages to user-space
=======================================================Before this series, not having PMD pages available would shut down THP support meaning that
/sys/kernel/mm/transparent_hugepagewould not be available. After this series,/sys/kernel/mm/transparent_hugepageandhpage_pmd_sizeare always available but hugepages-<PMD-size>kB is only available if PMD-sized pages are supported.To me this seems logical, as hugepages-<size>kB is only available if <size> is supported. If this is correct, then MM kselftests that depend on PMD-sized pages will need to be updated to check for it as they fail with this series applied when PMD-sized pages are not available.
The alternative is changing
hpage_pmd_size: either don't create the file when PMD-sized pages are not available or set hpage_pmd_size=0. My concern is that this could be considered an ABI breakage as this file was never reported to be optional or report a zero value.Testing
=======- Ran MM kselftests on
x86_64and s390
- Tested all mTHP sizes allocation onx86_64(with and without PMD-sized pages available)
- Tested shmem withwithin_sizew/ mTHP onx86_64(with and without PMD-sized pages available)
- Performed defconfig build onx86_64, s390, arm64, powerpc, and mipsNOTES:
* I'm forcingarch_has_pmd_leaves()off on x86 to simulate not having PMD-sized pages available* Running the MM kselftests when PMD pages are not available causes some tests that depend on PMD-sized THP pages to fail as noted earlier
Changelog
=========v8
--
- Fixed build breakage on MIPS (Lance)
- Rebased on top of mm-new (fixed conflicts ininclude/linux/pgtable.handmm/shmem.c- dropped a Reviewed-by as a result)v7
--
- Applied on top of latest mm-new
- Improved various changelogs including cover-letter
- Changedarch_has_pmd_leaves()default implementation to useIS_ENABLED()instead ofIS_BUILTIN()v6
--
- Rebased on top of mm-unstable (required a minor conflict resolution)
- Added more Reviewed-by and Acked-by tagsv5
--
- Movedinit_arch_has_pmd_leaves()tomm_core_init()(David)
- Renamedinit_arch_has_pmd_leaves()topgtable_leaf_support_init()(Lance)
- Added new patch changingshmem_getattr()to set blksize according to highest supported THP order (Baolin)
- Added new patches to movehas_transparent_hugepage()out ofCONFIG_TRANSPARENT_HUGEPAGEguards
-shmem_allowable_huge_orders(): rename variable and only disablePMD_ORDER(David)
- Added <linux/jmp_label.h> toinclude/linux/pgtable.h
- Added new tags and removed Reviewed-by from changed patchesv4
--
- Used static key forpgtable_has_pmd_leaves()API (Lance)
- Moved shmempgtable_has_pmd_leaves()check toshmem_allowable_huge_orders()(Baolin)
- Defaultpgtable_has_pmd_leaves()implementation toIS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)(Zi)
- Dropped patch “mm: thp: x86: cleanup PSE feature bit usage” (Dave)v3
--
- Rebased on top of latest Linus tree
- Removed i915 patch as driver droppedhas_transparent_hugepage()usage
- Movedinit_arch_has_pmd_leaves()call instart_kernel()to avoid conflict withearly_paramhandlers clearing CPU feature flags
- Fixed build error withCONFIG_MMU=n(kernel test robot)
- Fixedhuge_anon_orders_inheritdefault setting when !pgtable_has_pmd_leaves() (Baolin)
- Small commit changelog improvementsv2
--
- Added support for always enabling mTHPs for shmem (Baolin)
- Improved commits changelog & added reviewed-byv1
--
- Callinit_arch_has_pmd_leaves()fromstart_kernel()
- Keeppgtable_has_pmd_leaves()calls tied toCONFIG_TRANSPARENT_HUGEPAGE(David)
- ClearPUD_ORDERwhen clearingPMD_ORDER(David)
- Small changelog improvements (David)
- Rebased on top of latest mm-newLuiz Capitulino (14):
docs: tmpfs: remove implementation detail reference
mm: shmem:shmem_getattr(): set blksize to highest supported THP order
mm: introducepgtable_has_pmd_leaves()
drivers: dax: usepgtable_has_pmd_leaves()
drivers: nvdimm: usepgtable_has_pmd_leaves()
mm:debug_vm_pgtable: usepgtable_has_pmd_leaves()
mm: shmem: allow THP support determination at folio allocation time
s390: movehas_transparent_hugepage()out of THP guard
powerpc: movehas_transparent_hugepage()out of THP guard
mips: movehas_transparent_hugepage()out of THP guard
x86: movehas_transparent_hugepage()out of THP guard
treewide: introducearch_has_pmd_leaves()
mm: replacethp_disabled_by_hw()withpgtable_has_pmd_leaves()
mm: thp: always enable mTHP supportDocumentation/filesystems/tmpfs.rst | 5 ++-- arch/mips/include/asm/pgtable.h | 6 ++-- arch/mips/mm/pgtable.c | 25 ++++++++++++++++ arch/mips/mm/tlb-r4k.c | 22 -------------- 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 | 18 ++++++------ arch/powerpc/include/asm/book3s/64/radix.h | 14 ++++----- arch/powerpc/mm/book3s64/hash_pgtable.c | 8 ++--- arch/s390/include/asm/pgtable.h | 6 ++-- arch/x86/include/asm/pgtable.h | 12 ++++---- drivers/dax/dax-private.h | 2 +- drivers/nvdimm/pfn_devs.c | 6 ++-- include/linux/huge_mm.h | 7 ----- include/linux/pgtable.h | 21 ++++++++++++-- mm/debug_vm_pgtable.c | 20 ++++++------- mm/huge_memory.c | 27 ++++++++++++----- mm/memory.c | 11 ++++++- mm/mm_init.c | 1 + mm/shmem.c | 29 ++++++++++++------- 20 files changed, 144 insertions(+), 100 deletions(-)
Quoted 11 lines · Usama Arif
Quoted 6 lines · Luiz Capitulino
Introduction
============Today, if an architecture implements
has_transparent_hugepage()and the CPU lacks support for PMD-sized pages, the THP code disables all THP, including mTHP.
Quoted 6 lines
Hi Luiz,
Sorry for asking this so late in the series, but which CPUs lack support for PMD sized pages?
Is this series mainly for PowerPC?
No :)
The architectures that have conditional PMD page support (ie. discovered at run-time via has_transparent_hugepage()) are x86, s390, powerpc and mips.
For x86 for example, even on 64-bit there are cases where the PSE bit may not be present (eg. some errata and by hypervisor CPUID masking).
That being said, the main goal of the series is that has_transparent_hugepage() is overloaded: it has different semantics on those architectures and is used to gate all THP support (which is not the right thing to do for mTHP).
Quoted 177 lines
Thanks,
UsamaQuoted 172 lines
This happens because the
has_transparent_hugepage()helper is overloaded:
its name implies it checks whether THP is enabled, but on some architectures it actually checks whether the CPU supports PMD-sized pages. In addition, the THP and shmem code have a big switch onhas_transparent_hugepage().This series solves this by decoupling THP availability checking from querying CPU support for PMD-sized pages. THP availability can be checked with
IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE). For querying PMD-sized page support, this series introduces a new helper calledpgtable_has_pmd_leaves(), which is independent of THP, has well defined semantics and can be used in fast paths.Core THP code and shmem can use
pgtable_has_pmd_leaves()to determine PMD-sized THP support at page fault time (or folio allocation time for shmem), leaving THP and shmem always enabled for other THP sizes. For architectures and CPUs that do support PMD-sized pages there's no intended change in behavior.We also convert each user of
has_transparent_hugepage(), and the related helperthp_disabled_by_hw(), toIS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)and/orpgtable_has_pmd_leaves()according to the call site's check semantics. On s390, powerpc, mips and x86 the archhas_transparent_hugepage()implementation is moved out of theCONFIG_TRANSPARENT_HUGEPAGEguard and renamed toarch_has_pmd_leaves().Thanks to David Hildenbrand for suggesting this improvement and for providing initial guidance (all bugs and misconceptions are mine).
This applies to mm-new
93f615a22169("mm/swap, PM: hibernate: atomically replace hibernation pin").Reporting availability of PMD-sized pages to user-space
=======================================================Before this series, not having PMD pages available would shut down THP support meaning that
/sys/kernel/mm/transparent_hugepagewould not be available. After this series,/sys/kernel/mm/transparent_hugepageandhpage_pmd_sizeare always available but hugepages-<PMD-size>kB is only available if PMD-sized pages are supported.To me this seems logical, as hugepages-<size>kB is only available if <size> is supported. If this is correct, then MM kselftests that depend on PMD-sized pages will need to be updated to check for it as they fail with this series applied when PMD-sized pages are not available.
The alternative is changing
hpage_pmd_size: either don't create the file when PMD-sized pages are not available or set hpage_pmd_size=0. My concern is that this could be considered an ABI breakage as this file was never reported to be optional or report a zero value.Testing
=======- Ran MM kselftests on
x86_64and s390
- Tested all mTHP sizes allocation onx86_64(with and without PMD-sized pages available)
- Tested shmem withwithin_sizew/ mTHP onx86_64(with and without PMD-sized pages available)
- Performed defconfig build onx86_64, s390, arm64, powerpc, and mipsNOTES:
* I'm forcingarch_has_pmd_leaves()off on x86 to simulate not having PMD-sized pages available* Running the MM kselftests when PMD pages are not available causes some tests that depend on PMD-sized THP pages to fail as noted earlier
Changelog
=========v8
--
- Fixed build breakage on MIPS (Lance)
- Rebased on top of mm-new (fixed conflicts ininclude/linux/pgtable.handmm/shmem.c- dropped a Reviewed-by as a result)v7
--
- Applied on top of latest mm-new
- Improved various changelogs including cover-letter
- Changedarch_has_pmd_leaves()default implementation to useIS_ENABLED()instead ofIS_BUILTIN()v6
--
- Rebased on top of mm-unstable (required a minor conflict resolution)
- Added more Reviewed-by and Acked-by tagsv5
--
- Movedinit_arch_has_pmd_leaves()tomm_core_init()(David)
- Renamedinit_arch_has_pmd_leaves()topgtable_leaf_support_init()(Lance)
- Added new patch changingshmem_getattr()to set blksize according to highest supported THP order (Baolin)
- Added new patches to movehas_transparent_hugepage()out ofCONFIG_TRANSPARENT_HUGEPAGEguards
-shmem_allowable_huge_orders(): rename variable and only disablePMD_ORDER(David)
- Added <linux/jmp_label.h> toinclude/linux/pgtable.h
- Added new tags and removed Reviewed-by from changed patchesv4
--
- Used static key forpgtable_has_pmd_leaves()API (Lance)
- Moved shmempgtable_has_pmd_leaves()check toshmem_allowable_huge_orders()(Baolin)
- Defaultpgtable_has_pmd_leaves()implementation toIS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)(Zi)
- Dropped patch “mm: thp: x86: cleanup PSE feature bit usage” (Dave)v3
--
- Rebased on top of latest Linus tree
- Removed i915 patch as driver droppedhas_transparent_hugepage()usage
- Movedinit_arch_has_pmd_leaves()call instart_kernel()to avoid conflict withearly_paramhandlers clearing CPU feature flags
- Fixed build error withCONFIG_MMU=n(kernel test robot)
- Fixedhuge_anon_orders_inheritdefault setting when !pgtable_has_pmd_leaves() (Baolin)
- Small commit changelog improvementsv2
--
- Added support for always enabling mTHPs for shmem (Baolin)
- Improved commits changelog & added reviewed-byv1
--
- Callinit_arch_has_pmd_leaves()fromstart_kernel()
- Keeppgtable_has_pmd_leaves()calls tied toCONFIG_TRANSPARENT_HUGEPAGE(David)
- ClearPUD_ORDERwhen clearingPMD_ORDER(David)
- Small changelog improvements (David)
- Rebased on top of latest mm-newLuiz Capitulino (14):
docs: tmpfs: remove implementation detail reference
mm: shmem:shmem_getattr(): set blksize to highest supported THP order
mm: introducepgtable_has_pmd_leaves()
drivers: dax: usepgtable_has_pmd_leaves()
drivers: nvdimm: usepgtable_has_pmd_leaves()
mm:debug_vm_pgtable: usepgtable_has_pmd_leaves()
mm: shmem: allow THP support determination at folio allocation time
s390: movehas_transparent_hugepage()out of THP guard
powerpc: movehas_transparent_hugepage()out of THP guard
mips: movehas_transparent_hugepage()out of THP guard
x86: movehas_transparent_hugepage()out of THP guard
treewide: introducearch_has_pmd_leaves()
mm: replacethp_disabled_by_hw()withpgtable_has_pmd_leaves()
mm: thp: always enable mTHP supportDocumentation/filesystems/tmpfs.rst | 5 ++-- arch/mips/include/asm/pgtable.h | 6 ++-- arch/mips/mm/pgtable.c | 25 ++++++++++++++++ arch/mips/mm/tlb-r4k.c | 22 -------------- 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 | 18 ++++++------ arch/powerpc/include/asm/book3s/64/radix.h | 14 ++++----- arch/powerpc/mm/book3s64/hash_pgtable.c | 8 ++--- arch/s390/include/asm/pgtable.h | 6 ++-- arch/x86/include/asm/pgtable.h | 12 ++++---- drivers/dax/dax-private.h | 2 +- drivers/nvdimm/pfn_devs.c | 6 ++-- include/linux/huge_mm.h | 7 ----- include/linux/pgtable.h | 21 ++++++++++++-- mm/debug_vm_pgtable.c | 20 ++++++------- mm/huge_memory.c | 27 ++++++++++++----- mm/memory.c | 11 ++++++- mm/mm_init.c | 1 + mm/shmem.c | 29 ++++++++++++------- 20 files changed, 144 insertions(+), 100 deletions(-)
David Hildenbrand (Arm)
maintainerQuoted 27 lines · Luiz Capitulino
Quoted 11 lines · Usama Arif
Quoted 6 lines · Luiz Capitulino
Introduction
============Today, if an architecture implements
has_transparent_hugepage()and the CPU lacks support for PMD-sized pages, the THP code disables all THP, including mTHP.Quoted 6 lines
Hi Luiz,
Sorry for asking this so late in the series, but which CPUs lack support for PMD sized pages?
Is this series mainly for PowerPC?
No :)
The architectures that have conditional PMD page support (ie. discovered at run-time via
has_transparent_hugepage()) are x86, s390, powerpc and mips.
Quoted 7 lines
For x86 for example, even on 64-bit there are cases where the PSE bit may not be present (eg. some errata and by hypervisor CPUID masking).
That being said, the main goal of the series is that
has_transparent_hugepage()is overloaded: it has different semantics on those architectures and is used to gate all THP support (which is not the right thing to do for mTHP).
Yes, and I hope that we can then follow-up with similar PUD support cleanup to rework some of that CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD magic.
Signature · 3 lines
Cheers, David
Quoted 27 lines · On Fri, 18 Sep 2026 10:01:35 -0400 Luiz Capitulino <[email protected]> wrote:
Quoted 11 lines · Usama Arif
Quoted 6 lines · Luiz Capitulino
Introduction
============Today, if an architecture implements
has_transparent_hugepage()and the CPU lacks support for PMD-sized pages, the THP code disables all THP, including mTHP.Quoted 6 lines
Hi Luiz,
Sorry for asking this so late in the series, but which CPUs lack support for PMD sized pages?
Is this series mainly for PowerPC?
No :)
The architectures that have conditional PMD page support (ie. discovered at run-time via
has_transparent_hugepage()) are x86, s390, powerpc and mips.
Quoted 7 lines
For x86 for example, even on 64-bit there are cases where the PSE bit may not be present (eg. some errata and by hypervisor CPUID masking).
That being said, the main goal of the series is that
has_transparent_hugepage()is overloaded: it has different semantics on those architectures and is used to gate all THP support (which is not the right thing to do for mTHP).
Thanks for clearing that and the patches.
They all look good to me, apart from the the comment in the last patch.
Feel free to add
to all of them apart from last.
One nit: I would put the above goal of clean up at the start of the coverletter, instead of starting with adding mTHP support for CPUs that lack PMD.
Thanks,
Usama
Quoted 180 lines
Quoted 178 lines
Thanks,
UsamaQuoted 172 lines
This happens because the
has_transparent_hugepage()helper is overloaded:
its name implies it checks whether THP is enabled, but on some architectures it actually checks whether the CPU supports PMD-sized pages. In addition, the THP and shmem code have a big switch onhas_transparent_hugepage().This series solves this by decoupling THP availability checking from querying CPU support for PMD-sized pages. THP availability can be checked with
IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE). For querying PMD-sized page support, this series introduces a new helper calledpgtable_has_pmd_leaves(), which is independent of THP, has well defined semantics and can be used in fast paths.Core THP code and shmem can use
pgtable_has_pmd_leaves()to determine PMD-sized THP support at page fault time (or folio allocation time for shmem), leaving THP and shmem always enabled for other THP sizes. For architectures and CPUs that do support PMD-sized pages there's no intended change in behavior.We also convert each user of
has_transparent_hugepage(), and the related helperthp_disabled_by_hw(), toIS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)and/orpgtable_has_pmd_leaves()according to the call site's check semantics. On s390, powerpc, mips and x86 the archhas_transparent_hugepage()implementation is moved out of theCONFIG_TRANSPARENT_HUGEPAGEguard and renamed toarch_has_pmd_leaves().Thanks to David Hildenbrand for suggesting this improvement and for providing initial guidance (all bugs and misconceptions are mine).
This applies to mm-new
93f615a22169("mm/swap, PM: hibernate: atomically replace hibernation pin").Reporting availability of PMD-sized pages to user-space
=======================================================Before this series, not having PMD pages available would shut down THP support meaning that
/sys/kernel/mm/transparent_hugepagewould not be available. After this series,/sys/kernel/mm/transparent_hugepageandhpage_pmd_sizeare always available but hugepages-<PMD-size>kB is only available if PMD-sized pages are supported.To me this seems logical, as hugepages-<size>kB is only available if <size> is supported. If this is correct, then MM kselftests that depend on PMD-sized pages will need to be updated to check for it as they fail with this series applied when PMD-sized pages are not available.
The alternative is changing
hpage_pmd_size: either don't create the file when PMD-sized pages are not available or set hpage_pmd_size=0. My concern is that this could be considered an ABI breakage as this file was never reported to be optional or report a zero value.Testing
=======- Ran MM kselftests on
x86_64and s390
- Tested all mTHP sizes allocation onx86_64(with and without PMD-sized pages available)
- Tested shmem withwithin_sizew/ mTHP onx86_64(with and without PMD-sized pages available)
- Performed defconfig build onx86_64, s390, arm64, powerpc, and mipsNOTES:
* I'm forcingarch_has_pmd_leaves()off on x86 to simulate not having PMD-sized pages available* Running the MM kselftests when PMD pages are not available causes some tests that depend on PMD-sized THP pages to fail as noted earlier
Changelog
=========v8
--
- Fixed build breakage on MIPS (Lance)
- Rebased on top of mm-new (fixed conflicts ininclude/linux/pgtable.handmm/shmem.c- dropped a Reviewed-by as a result)v7
--
- Applied on top of latest mm-new
- Improved various changelogs including cover-letter
- Changedarch_has_pmd_leaves()default implementation to useIS_ENABLED()instead ofIS_BUILTIN()v6
--
- Rebased on top of mm-unstable (required a minor conflict resolution)
- Added more Reviewed-by and Acked-by tagsv5
--
- Movedinit_arch_has_pmd_leaves()tomm_core_init()(David)
- Renamedinit_arch_has_pmd_leaves()topgtable_leaf_support_init()(Lance)
- Added new patch changingshmem_getattr()to set blksize according to highest supported THP order (Baolin)
- Added new patches to movehas_transparent_hugepage()out ofCONFIG_TRANSPARENT_HUGEPAGEguards
-shmem_allowable_huge_orders(): rename variable and only disablePMD_ORDER(David)
- Added <linux/jmp_label.h> toinclude/linux/pgtable.h
- Added new tags and removed Reviewed-by from changed patchesv4
--
- Used static key forpgtable_has_pmd_leaves()API (Lance)
- Moved shmempgtable_has_pmd_leaves()check toshmem_allowable_huge_orders()(Baolin)
- Defaultpgtable_has_pmd_leaves()implementation toIS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)(Zi)
- Dropped patch “mm: thp: x86: cleanup PSE feature bit usage” (Dave)v3
--
- Rebased on top of latest Linus tree
- Removed i915 patch as driver droppedhas_transparent_hugepage()usage
- Movedinit_arch_has_pmd_leaves()call instart_kernel()to avoid conflict withearly_paramhandlers clearing CPU feature flags
- Fixed build error withCONFIG_MMU=n(kernel test robot)
- Fixedhuge_anon_orders_inheritdefault setting when !pgtable_has_pmd_leaves() (Baolin)
- Small commit changelog improvementsv2
--
- Added support for always enabling mTHPs for shmem (Baolin)
- Improved commits changelog & added reviewed-byv1
--
- Callinit_arch_has_pmd_leaves()fromstart_kernel()
- Keeppgtable_has_pmd_leaves()calls tied toCONFIG_TRANSPARENT_HUGEPAGE(David)
- ClearPUD_ORDERwhen clearingPMD_ORDER(David)
- Small changelog improvements (David)
- Rebased on top of latest mm-newLuiz Capitulino (14):
docs: tmpfs: remove implementation detail reference
mm: shmem:shmem_getattr(): set blksize to highest supported THP order
mm: introducepgtable_has_pmd_leaves()
drivers: dax: usepgtable_has_pmd_leaves()
drivers: nvdimm: usepgtable_has_pmd_leaves()
mm:debug_vm_pgtable: usepgtable_has_pmd_leaves()
mm: shmem: allow THP support determination at folio allocation time
s390: movehas_transparent_hugepage()out of THP guard
powerpc: movehas_transparent_hugepage()out of THP guard
mips: movehas_transparent_hugepage()out of THP guard
x86: movehas_transparent_hugepage()out of THP guard
treewide: introducearch_has_pmd_leaves()
mm: replacethp_disabled_by_hw()withpgtable_has_pmd_leaves()
mm: thp: always enable mTHP supportDocumentation/filesystems/tmpfs.rst | 5 ++-- arch/mips/include/asm/pgtable.h | 6 ++-- arch/mips/mm/pgtable.c | 25 ++++++++++++++++ arch/mips/mm/tlb-r4k.c | 22 -------------- 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 | 18 ++++++------ arch/powerpc/include/asm/book3s/64/radix.h | 14 ++++----- arch/powerpc/mm/book3s64/hash_pgtable.c | 8 ++--- arch/s390/include/asm/pgtable.h | 6 ++-- arch/x86/include/asm/pgtable.h | 12 ++++---- drivers/dax/dax-private.h | 2 +- drivers/nvdimm/pfn_devs.c | 6 ++-- include/linux/huge_mm.h | 7 ----- include/linux/pgtable.h | 21 ++++++++++++-- mm/debug_vm_pgtable.c | 20 ++++++------- mm/huge_memory.c | 27 ++++++++++++----- mm/memory.c | 11 ++++++- mm/mm_init.c | 1 + mm/shmem.c | 29 ++++++++++++------- 20 files changed, 144 insertions(+), 100 deletions(-)
Quoted 43 lines · Usama Arif
Quoted 27 lines · On Fri, 18 Sep 2026 10:01:35 -0400 Luiz Capitulino <[email protected]> wrote:
Quoted 11 lines · Usama Arif
Quoted 6 lines · Luiz Capitulino
Introduction
============Today, if an architecture implements
has_transparent_hugepage()and the CPU lacks support for PMD-sized pages, the THP code disables all THP, including mTHP.Quoted 6 lines
Hi Luiz,
Sorry for asking this so late in the series, but which CPUs lack support for PMD sized pages?
Is this series mainly for PowerPC?
No :)
The architectures that have conditional PMD page support (ie. discovered at run-time via
has_transparent_hugepage()) are x86, s390, powerpc and mips.Quoted 7 lines
For x86 for example, even on 64-bit there are cases where the PSE bit may not be present (eg. some errata and by hypervisor CPUID masking).
That being said, the main goal of the series is that
has_transparent_hugepage()is overloaded: it has different semantics on those architectures and is used to gate all THP support (which is not the right thing to do for mTHP).Thanks for clearing that and the patches.
They all look good to me, apart from the the comment in the last patch.
Feel free to add
Quoted 7 lines
Acked-by Usama Arif <[email protected]>to all of them apart from last.
One nit: I would put the above goal of clean up at the start of the coverletter, instead of starting with adding mTHP support for CPUs that lack PMD.
Thanks Usama, I appreciate the review. I'll do this if I need to send a new version.
Quoted 185 lines
Thanks,
UsamaQuoted 180 lines
Quoted 178 lines
Thanks,
UsamaQuoted 172 lines
This happens because the
has_transparent_hugepage()helper is overloaded:
its name implies it checks whether THP is enabled, but on some architectures it actually checks whether the CPU supports PMD-sized pages. In addition, the THP and shmem code have a big switch onhas_transparent_hugepage().This series solves this by decoupling THP availability checking from querying CPU support for PMD-sized pages. THP availability can be checked with
IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE). For querying PMD-sized page support, this series introduces a new helper calledpgtable_has_pmd_leaves(), which is independent of THP, has well defined semantics and can be used in fast paths.Core THP code and shmem can use
pgtable_has_pmd_leaves()to determine PMD-sized THP support at page fault time (or folio allocation time for shmem), leaving THP and shmem always enabled for other THP sizes. For architectures and CPUs that do support PMD-sized pages there's no intended change in behavior.We also convert each user of
has_transparent_hugepage(), and the related helperthp_disabled_by_hw(), toIS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)and/orpgtable_has_pmd_leaves()according to the call site's check semantics. On s390, powerpc, mips and x86 the archhas_transparent_hugepage()implementation is moved out of theCONFIG_TRANSPARENT_HUGEPAGEguard and renamed toarch_has_pmd_leaves().Thanks to David Hildenbrand for suggesting this improvement and for providing initial guidance (all bugs and misconceptions are mine).
This applies to mm-new
93f615a22169("mm/swap, PM: hibernate: atomically replace hibernation pin").Reporting availability of PMD-sized pages to user-space
=======================================================Before this series, not having PMD pages available would shut down THP support meaning that
/sys/kernel/mm/transparent_hugepagewould not be available. After this series,/sys/kernel/mm/transparent_hugepageandhpage_pmd_sizeare always available but hugepages-<PMD-size>kB is only available if PMD-sized pages are supported.To me this seems logical, as hugepages-<size>kB is only available if <size> is supported. If this is correct, then MM kselftests that depend on PMD-sized pages will need to be updated to check for it as they fail with this series applied when PMD-sized pages are not available.
The alternative is changing
hpage_pmd_size: either don't create the file when PMD-sized pages are not available or set hpage_pmd_size=0. My concern is that this could be considered an ABI breakage as this file was never reported to be optional or report a zero value.Testing
=======- Ran MM kselftests on
x86_64and s390
- Tested all mTHP sizes allocation onx86_64(with and without PMD-sized pages available)
- Tested shmem withwithin_sizew/ mTHP onx86_64(with and without PMD-sized pages available)
- Performed defconfig build onx86_64, s390, arm64, powerpc, and mipsNOTES:
* I'm forcingarch_has_pmd_leaves()off on x86 to simulate not having PMD-sized pages available* Running the MM kselftests when PMD pages are not available causes some tests that depend on PMD-sized THP pages to fail as noted earlier
Changelog
=========v8
--
- Fixed build breakage on MIPS (Lance)
- Rebased on top of mm-new (fixed conflicts ininclude/linux/pgtable.handmm/shmem.c- dropped a Reviewed-by as a result)v7
--
- Applied on top of latest mm-new
- Improved various changelogs including cover-letter
- Changedarch_has_pmd_leaves()default implementation to useIS_ENABLED()instead ofIS_BUILTIN()v6
--
- Rebased on top of mm-unstable (required a minor conflict resolution)
- Added more Reviewed-by and Acked-by tagsv5
--
- Movedinit_arch_has_pmd_leaves()tomm_core_init()(David)
- Renamedinit_arch_has_pmd_leaves()topgtable_leaf_support_init()(Lance)
- Added new patch changingshmem_getattr()to set blksize according to highest supported THP order (Baolin)
- Added new patches to movehas_transparent_hugepage()out ofCONFIG_TRANSPARENT_HUGEPAGEguards
-shmem_allowable_huge_orders(): rename variable and only disablePMD_ORDER(David)
- Added <linux/jmp_label.h> toinclude/linux/pgtable.h
- Added new tags and removed Reviewed-by from changed patchesv4
--
- Used static key forpgtable_has_pmd_leaves()API (Lance)
- Moved shmempgtable_has_pmd_leaves()check toshmem_allowable_huge_orders()(Baolin)
- Defaultpgtable_has_pmd_leaves()implementation toIS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)(Zi)
- Dropped patch “mm: thp: x86: cleanup PSE feature bit usage” (Dave)v3
--
- Rebased on top of latest Linus tree
- Removed i915 patch as driver droppedhas_transparent_hugepage()usage
- Movedinit_arch_has_pmd_leaves()call instart_kernel()to avoid conflict withearly_paramhandlers clearing CPU feature flags
- Fixed build error withCONFIG_MMU=n(kernel test robot)
- Fixedhuge_anon_orders_inheritdefault setting when !pgtable_has_pmd_leaves() (Baolin)
- Small commit changelog improvementsv2
--
- Added support for always enabling mTHPs for shmem (Baolin)
- Improved commits changelog & added reviewed-byv1
--
- Callinit_arch_has_pmd_leaves()fromstart_kernel()
- Keeppgtable_has_pmd_leaves()calls tied toCONFIG_TRANSPARENT_HUGEPAGE(David)
- ClearPUD_ORDERwhen clearingPMD_ORDER(David)
- Small changelog improvements (David)
- Rebased on top of latest mm-newLuiz Capitulino (14):
docs: tmpfs: remove implementation detail reference
mm: shmem:shmem_getattr(): set blksize to highest supported THP order
mm: introducepgtable_has_pmd_leaves()
drivers: dax: usepgtable_has_pmd_leaves()
drivers: nvdimm: usepgtable_has_pmd_leaves()
mm:debug_vm_pgtable: usepgtable_has_pmd_leaves()
mm: shmem: allow THP support determination at folio allocation time
s390: movehas_transparent_hugepage()out of THP guard
powerpc: movehas_transparent_hugepage()out of THP guard
mips: movehas_transparent_hugepage()out of THP guard
x86: movehas_transparent_hugepage()out of THP guard
treewide: introducearch_has_pmd_leaves()
mm: replacethp_disabled_by_hw()withpgtable_has_pmd_leaves()
mm: thp: always enable mTHP supportDocumentation/filesystems/tmpfs.rst | 5 ++-- arch/mips/include/asm/pgtable.h | 6 ++-- arch/mips/mm/pgtable.c | 25 ++++++++++++++++ arch/mips/mm/tlb-r4k.c | 22 -------------- 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 | 18 ++++++------ arch/powerpc/include/asm/book3s/64/radix.h | 14 ++++----- arch/powerpc/mm/book3s64/hash_pgtable.c | 8 ++--- arch/s390/include/asm/pgtable.h | 6 ++-- arch/x86/include/asm/pgtable.h | 12 ++++---- drivers/dax/dax-private.h | 2 +- drivers/nvdimm/pfn_devs.c | 6 ++-- include/linux/huge_mm.h | 7 ----- include/linux/pgtable.h | 21 ++++++++++++-- mm/debug_vm_pgtable.c | 20 ++++++------- mm/huge_memory.c | 27 ++++++++++++----- mm/memory.c | 11 ++++++- mm/mm_init.c | 1 + mm/shmem.c | 29 ++++++++++++------- 20 files changed, 144 insertions(+), 100 deletions(-)