linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [RFC 00/10] mm: thp: always enable mTHP support
@ 2025-11-06 21:28 Luiz Capitulino
  2025-11-06 21:28 ` [RFC 01/10] docs: tmpfs: remove implementation detail reference Luiz Capitulino
                   ` (10 more replies)
  0 siblings, 11 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

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 support. In addition, the kernel lacks a well defined API to check for
PMD-sized page support. It currently relies on has_transparent_hugepage()
and thp_disabled_by_hw(), but they are not well defined and are tied to
THP support.

This series addresses both issues by introducing a new well defined API
to query PMD-sized page support: pgtable_has_pmd_leaves(). Using this
new helper, we ensure that mTHP remains enabled even when the
architecture or CPU doesn't support PMD-sized pages.

An important detail is that we need to do the same refactoring for
has_transparent_pud_hugepage(). I actually have patches for this one
too, I'm not including them here because I want to get some initial
feedback on the general approach first (and maybe it's better to
do that in a separate series).

Thanks to David Hildenbrand for suggesting this improvement and for
providing guidance (all bugs and misconcentpions are mine).

Luiz Capitulino (10):
  docs: tmpfs: remove implementation detail reference
  mm: introduce pgtable_has_pmd_leaves()
  drivers: dax: use pgtable_has_pmd_leaves()
  drivers: i915 selftest: use pgtable_has_pmd_leaves()
  drivers: nvdimm: use pgtable_has_pmd_leaves()
  mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
  treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves()
  mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves()
  mm: thp: always enable mTHP support
  mm: thp: x86: cleanup PSE feature bit usage

 Documentation/filesystems/tmpfs.rst           |  5 ++---
 arch/mips/include/asm/pgtable.h               |  4 ++--
 arch/mips/mm/tlb-r4k.c                        |  4 ++--
 arch/powerpc/include/asm/book3s/64/hash-4k.h  |  2 +-
 arch/powerpc/include/asm/book3s/64/hash-64k.h |  2 +-
 arch/powerpc/include/asm/book3s/64/pgtable.h  | 10 +++++-----
 arch/powerpc/include/asm/book3s/64/radix.h    |  2 +-
 arch/powerpc/mm/book3s64/hash_pgtable.c       |  4 ++--
 arch/s390/include/asm/pgtable.h               |  4 ++--
 arch/x86/include/asm/pgtable.h                |  6 ------
 arch/x86/include/asm/pgtable_32.h             |  6 ++++++
 drivers/dax/dax-private.h                     |  2 +-
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |  2 +-
 drivers/nvdimm/pfn_devs.c                     |  4 ++--
 include/linux/huge_mm.h                       |  7 -------
 include/linux/pgtable.h                       | 14 +++++++++++--
 mm/debug_vm_pgtable.c                         | 20 +++++++++----------
 mm/huge_memory.c                              | 13 ++++++------
 mm/memory.c                                   | 12 ++++++++++-
 mm/shmem.c                                    |  8 ++++----
 20 files changed, 72 insertions(+), 59 deletions(-)

-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 01/10] docs: tmpfs: remove implementation detail reference
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:26   ` David Hildenbrand (Red Hat)
  2025-11-06 21:28 ` [RFC 02/10] mm: introduce pgtable_has_pmd_leaves() Luiz Capitulino
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

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.

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 Documentation/filesystems/tmpfs.rst | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/filesystems/tmpfs.rst b/Documentation/filesystems/tmpfs.rst
index d677e0428c3f..46fc986c3388 100644
--- a/Documentation/filesystems/tmpfs.rst
+++ b/Documentation/filesystems/tmpfs.rst
@@ -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.
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 02/10] mm: introduce pgtable_has_pmd_leaves()
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
  2025-11-06 21:28 ` [RFC 01/10] docs: tmpfs: remove implementation detail reference Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-06 21:28 ` [RFC 03/10] drivers: dax: use pgtable_has_pmd_leaves() Luiz Capitulino
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

This is a new helper which can be used to check if the architecture
supports PMD-sized pages. It's intended to replace two existing helpers:

- has_transparent_hugepages(): it's used to check for PMD-sized pages
  (not exactly THP support), but it may perform a hardware check so it's
  not intended to be used in fast paths

- thp_disabled_by_hw(): also checks for PMD-sized pages support, but
  uses a cached value

pgtable_has_pmd_leaves() implementation is split in two parts:

1. init_arch_has_pmd_leaves(): runs at boottime as early_initcall as a
   wrapper to has_transparent_hugepages(). The result is cached

2. pgtable_has_pmd_leaves(): just returns the cached value

The next commits will convert users of both has_transparent_hugepages()
and thp_disabled_by_hw() to pgtable_has_pmd_leaves().

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 include/linux/pgtable.h | 10 ++++++++++
 mm/memory.c             | 10 ++++++++++
 2 files changed, 20 insertions(+)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 32e8457ad535..e4c5f70b0a01 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -2001,6 +2001,16 @@ static inline const char *pgtable_level_to_str(enum pgtable_level level)
 	}
 }
 
+/*
+ * IMPORTANT: pgtable_has_pmd_leaves() can only be called after
+ * early_initcall, since that's when __arch_has_pmd_leaves is set
+ */
+extern bool __arch_has_pmd_leaves;
+static inline bool pgtable_has_pmd_leaves(void)
+{
+	return __arch_has_pmd_leaves;
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #if !defined(MAX_POSSIBLE_PHYSMEM_BITS) && !defined(CONFIG_64BIT)
diff --git a/mm/memory.c b/mm/memory.c
index 74b45e258323..7b50f3ec9b37 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -176,6 +176,16 @@ static int __init init_zero_pfn(void)
 }
 early_initcall(init_zero_pfn);
 
+bool __arch_has_pmd_leaves __read_mostly;
+EXPORT_SYMBOL(__arch_has_pmd_leaves);
+
+static int __init init_arch_has_pmd_leaves(void)
+{
+	__arch_has_pmd_leaves = has_transparent_hugepage();
+	return 0;
+}
+early_initcall(init_arch_has_pmd_leaves);
+
 void mm_trace_rss_stat(struct mm_struct *mm, int member)
 {
 	trace_rss_stat(mm, member);
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 03/10] drivers: dax: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
  2025-11-06 21:28 ` [RFC 01/10] docs: tmpfs: remove implementation detail reference Luiz Capitulino
  2025-11-06 21:28 ` [RFC 02/10] mm: introduce pgtable_has_pmd_leaves() Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:28   ` David Hildenbrand (Red Hat)
  2025-11-06 21:28 ` [RFC 04/10] drivers: i915 selftest: " Luiz Capitulino
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

dav_align_valid() uses has_transparent_hugepage() to check if PMD-sized
pages are supported, use pgtable_has_pmd_leaves() instead.

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 drivers/dax/dax-private.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h
index 0867115aeef2..10aeaec9e789 100644
--- a/drivers/dax/dax-private.h
+++ b/drivers/dax/dax-private.h
@@ -117,7 +117,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;
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 04/10] drivers: i915 selftest: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (2 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 03/10] drivers: dax: use pgtable_has_pmd_leaves() Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:29   ` David Hildenbrand (Red Hat)
  2025-11-17 17:30   ` David Hildenbrand (Red Hat)
  2025-11-06 21:28 ` [RFC 05/10] drivers: nvdimm: " Luiz Capitulino
                   ` (6 subsequent siblings)
  10 siblings, 2 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

igt_can_allocate_thp() uses has_transparente_hugepage() to check if
PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index bd08605a1611..c76aafa36d2b 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -1316,7 +1316,7 @@ typedef struct drm_i915_gem_object *
 
 static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
 {
-	return i915->mm.gemfs && has_transparent_hugepage();
+	return i915->mm.gemfs && pgtable_has_pmd_leaves();
 }
 
 static struct drm_i915_gem_object *
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 05/10] drivers: nvdimm: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (3 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 04/10] drivers: i915 selftest: " Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:32   ` David Hildenbrand (Red Hat)
  2025-11-06 21:28 ` [RFC 06/10] mm: debug_vm_pgtable: " Luiz Capitulino
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

nd_pfn_supported_alignments() and nd_pfn_supported_alignments() use
has_transparent_hugepage() to check if PMD-sized pages are supported,
use pgtable_has_pmd_leaves() instead.

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 drivers/nvdimm/pfn_devs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index 42b172fc5576..989f87f07e0c 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -94,7 +94,7 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)
 
 	alignments[0] = PAGE_SIZE;
 
-	if (has_transparent_hugepage()) {
+	if (pgtable_has_pmd_leaves()) {
 		alignments[1] = HPAGE_PMD_SIZE;
 		if (has_transparent_pud_hugepage())
 			alignments[2] = HPAGE_PUD_SIZE;
@@ -109,7 +109,7 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)
 static unsigned long nd_pfn_default_alignment(void)
 {
 
-	if (has_transparent_hugepage())
+	if (pgtable_has_pmd_leaves())
 		return HPAGE_PMD_SIZE;
 	return PAGE_SIZE;
 }
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 06/10] mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (4 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 05/10] drivers: nvdimm: " Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:40   ` David Hildenbrand (Red Hat)
  2025-11-06 21:28 ` [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves() Luiz Capitulino
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

debug_vm_pgtable calls has_transparent_hugepage() in multiple places to
check if PMD-sized pages are supported, use pgtable_has_pmd_leaves()
instead.

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 mm/debug_vm_pgtable.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index 830107b6dd08..241b36c78ac9 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -170,7 +170,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);
@@ -208,7 +208,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;
@@ -269,7 +269,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");
@@ -674,7 +674,7 @@ static void __init pmd_protnone_tests(struct pgtable_debug_args *args)
 	if (!IS_ENABLED(CONFIG_NUMA_BALANCING))
 		return;
 
-	if (!has_transparent_hugepage())
+	if (!pgtable_has_pmd_leaves())
 		return;
 
 	pr_debug("Validating PMD protnone\n");
@@ -721,7 +721,7 @@ static void __init pmd_soft_dirty_tests(struct pgtable_debug_args *args)
 	if (!IS_ENABLED(CONFIG_MEM_SOFT_DIRTY))
 		return;
 
-	if (!has_transparent_hugepage())
+	if (!pgtable_has_pmd_leaves())
 		return;
 
 	pr_debug("Validating PMD soft dirty\n");
@@ -738,7 +738,7 @@ static void __init pmd_swap_soft_dirty_tests(struct pgtable_debug_args *args)
 		!IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION))
 		return;
 
-	if (!has_transparent_hugepage())
+	if (!pgtable_has_pmd_leaves())
 		return;
 
 	pr_debug("Validating PMD swap soft dirty\n");
@@ -801,7 +801,7 @@ static void __init pmd_swap_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");
@@ -881,7 +881,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");
@@ -968,7 +968,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) {
 		if (args->is_contiguous_page) {
 			free_contig_range(args->pmd_pfn, (1 << HPAGE_PMD_ORDER));
@@ -1226,7 +1226,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);
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves()
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (5 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 06/10] mm: debug_vm_pgtable: " Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:45   ` David Hildenbrand (Red Hat)
  2025-11-06 21:28 ` [RFC 08/10] mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves() Luiz Capitulino
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

Now that the majority of has_transparent_hugepage() callers have been
converted to pgtable_has_pmd_leaves(), rename has_transparent_hugepage()
to arch_has_pmd_leaves() since that's what the helper checks for.

arch_has_pmd_leaves() is supposed to be called only by
init_arch_has_pmd_leaves(), except for two exeptions:

1. shmem: shmem code runs very early during boot so it can't use
   pgtable_has_pmd_leaves()
2. hugepage_init(): just a temporary exception, this function will be
   converted in a future commit

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 arch/mips/include/asm/pgtable.h               |  4 ++--
 arch/mips/mm/tlb-r4k.c                        |  4 ++--
 arch/powerpc/include/asm/book3s/64/hash-4k.h  |  2 +-
 arch/powerpc/include/asm/book3s/64/hash-64k.h |  2 +-
 arch/powerpc/include/asm/book3s/64/pgtable.h  | 10 +++++-----
 arch/powerpc/include/asm/book3s/64/radix.h    |  2 +-
 arch/powerpc/mm/book3s64/hash_pgtable.c       |  4 ++--
 arch/s390/include/asm/pgtable.h               |  4 ++--
 arch/x86/include/asm/pgtable.h                |  4 ++--
 include/linux/pgtable.h                       |  4 ++--
 mm/huge_memory.c                              |  2 +-
 mm/memory.c                                   |  2 +-
 mm/shmem.c                                    |  6 +++---
 13 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index ae73ecf4c41a..fb9539002392 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -616,8 +616,8 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long vaddr,
 /* We don't have hardware dirty/accessed bits, generic_pmdp_establish is fine.*/
 #define pmdp_establish generic_pmdp_establish
 
-#define has_transparent_hugepage has_transparent_hugepage
-extern int has_transparent_hugepage(void);
+#define arch_has_pmd_leaves arch_has_pmd_leaves
+extern int arch_has_pmd_leaves(void);
 
 static inline int pmd_trans_huge(pmd_t pmd)
 {
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 347126dc010d..eb16ddedb40c 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -430,7 +430,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 
-int has_transparent_hugepage(void)
+int arch_has_pmd_leaves(void)
 {
 	static unsigned int mask = -1;
 
@@ -446,7 +446,7 @@ int has_transparent_hugepage(void)
 	}
 	return mask == PM_HUGE_MASK;
 }
-EXPORT_SYMBOL(has_transparent_hugepage);
+EXPORT_SYMBOL(arch_has_pmd_leaves);
 
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE  */
 
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index 8e5bd9902bed..6744c2287199 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -165,7 +165,7 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
 extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
 extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
 				       unsigned long addr, pmd_t *pmdp);
-extern int hash__has_transparent_hugepage(void);
+extern int hash__arch_has_pmd_leaves(void);
 #endif
 
 #endif /* !__ASSEMBLER__ */
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h
index 7deb3a66890b..9392aba5e5dc 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -278,7 +278,7 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
 extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
 extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
 				       unsigned long addr, pmd_t *pmdp);
-extern int hash__has_transparent_hugepage(void);
+extern int hash__arch_has_pmd_leaves(void);
 #endif /*  CONFIG_TRANSPARENT_HUGEPAGE */
 
 #endif	/* __ASSEMBLER__ */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index aac8ce30cd3b..6ed036b3d3c2 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -1094,14 +1094,14 @@ static inline void update_mmu_cache_pud(struct vm_area_struct *vma,
 {
 }
 
-extern int hash__has_transparent_hugepage(void);
-static inline int has_transparent_hugepage(void)
+extern int hash__arch_has_pmd_leaves(void);
+static inline int arch_has_pmd_leaves(void)
 {
 	if (radix_enabled())
-		return radix__has_transparent_hugepage();
-	return hash__has_transparent_hugepage();
+		return radix__arch_has_pmd_leaves();
+	return hash__arch_has_pmd_leaves();
 }
-#define has_transparent_hugepage has_transparent_hugepage
+#define arch_has_pmd_leaves arch_has_pmd_leaves
 
 static inline int has_transparent_pud_hugepage(void)
 {
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index da954e779744..c884a119cbd9 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -298,7 +298,7 @@ extern pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm,
 pud_t radix__pudp_huge_get_and_clear(struct mm_struct *mm,
 				     unsigned long addr, pud_t *pudp);
 
-static inline int radix__has_transparent_hugepage(void)
+static inline int radix__arch_has_pmd_leaves(void)
 {
 	/* For radix 2M at PMD level means thp */
 	if (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT)
diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c
index 82d31177630b..1dec64bf0c75 100644
--- a/arch/powerpc/mm/book3s64/hash_pgtable.c
+++ b/arch/powerpc/mm/book3s64/hash_pgtable.c
@@ -366,7 +366,7 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
 	return old_pmd;
 }
 
-int hash__has_transparent_hugepage(void)
+int hash__arch_has_pmd_leaves(void)
 {
 
 	if (!mmu_has_feature(MMU_FTR_16M_PAGE))
@@ -395,7 +395,7 @@ int hash__has_transparent_hugepage(void)
 
 	return 1;
 }
-EXPORT_SYMBOL_GPL(hash__has_transparent_hugepage);
+EXPORT_SYMBOL_GPL(hash__arch_has_pmd_leaves);
 
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index b7100c6a4054..68fe444ace56 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -1881,8 +1881,8 @@ static inline int pmd_trans_huge(pmd_t pmd)
 	return pmd_leaf(pmd);
 }
 
-#define has_transparent_hugepage has_transparent_hugepage
-static inline int has_transparent_hugepage(void)
+#define arch_has_pmd_leaves arch_has_pmd_leaves
+static inline int arch_has_pmd_leaves(void)
 {
 	return cpu_has_edat1() ? 1 : 0;
 }
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index e33df3da6980..08d109280e36 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -313,8 +313,8 @@ static inline int pud_trans_huge(pud_t pud)
 }
 #endif
 
-#define has_transparent_hugepage has_transparent_hugepage
-static inline int has_transparent_hugepage(void)
+#define arch_has_pmd_leaves arch_has_pmd_leaves
+static inline int arch_has_pmd_leaves(void)
 {
 	return boot_cpu_has(X86_FEATURE_PSE);
 }
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index e4c5f70b0a01..02a2772ec548 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -2026,8 +2026,8 @@ static inline bool pgtable_has_pmd_leaves(void)
 #endif
 #endif
 
-#ifndef has_transparent_hugepage
-#define has_transparent_hugepage() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
+#ifndef arch_has_pmd_leaves
+#define arch_has_pmd_leaves() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
 #endif
 
 #ifndef has_transparent_pud_hugepage
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 1d1b74950332..9bfa11aa2cbc 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -904,7 +904,7 @@ static int __init hugepage_init(void)
 	int err;
 	struct kobject *hugepage_kobj;
 
-	if (!has_transparent_hugepage()) {
+	if (!arch_has_pmd_leaves()) {
 		transparent_hugepage_flags = 1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED;
 		return -EINVAL;
 	}
diff --git a/mm/memory.c b/mm/memory.c
index 7b50f3ec9b37..6702c9187114 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -181,7 +181,7 @@ EXPORT_SYMBOL(__arch_has_pmd_leaves);
 
 static int __init init_arch_has_pmd_leaves(void)
 {
-	__arch_has_pmd_leaves = has_transparent_hugepage();
+	__arch_has_pmd_leaves = arch_has_pmd_leaves();
 	return 0;
 }
 early_initcall(init_arch_has_pmd_leaves);
diff --git a/mm/shmem.c b/mm/shmem.c
index b9081b817d28..48312b7727a7 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -672,7 +672,7 @@ static int shmem_parse_huge(const char *str)
 	else
 		return -EINVAL;
 
-	if (!has_transparent_hugepage() &&
+	if (!arch_has_pmd_leaves() &&
 	    huge != SHMEM_HUGE_NEVER && huge != SHMEM_HUGE_DENY)
 		return -EINVAL;
 
@@ -4646,7 +4646,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
 		ctx->huge = result.uint_32;
 		if (ctx->huge != SHMEM_HUGE_NEVER &&
 		    !(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
-		      has_transparent_hugepage()))
+		      arch_has_pmd_leaves()))
 			goto unsupported_parameter;
 		ctx->seen |= SHMEM_SEEN_HUGE;
 		break;
@@ -5430,7 +5430,7 @@ void __init shmem_init(void)
 #endif
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-	if (has_transparent_hugepage() && shmem_huge > SHMEM_HUGE_DENY)
+	if (arch_has_pmd_leaves() && 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 */
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 08/10] mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves()
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (6 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves() Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-06 21:28 ` [RFC 09/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

Despite its name, thp_disabled_by_hw() only checks whether the
architecture supports PMD-sized pages. It returns true when
TRANSPARENT_HUGEPAGE_UNSUPPORTED is set, which occurs if the
architecture implements arch_has_pmd_leaves() and that function
returns false.

Since pgtable_has_pmd_leaves() provide the same semantics, use it
instead.

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 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(-)

diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index f327d62fc985..63d75a2897dd 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -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,
@@ -352,12 +351,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_vmflags(struct file *filp, unsigned long addr,
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 9bfa11aa2cbc..0f016ea7082d 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -122,7 +122,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. */
@@ -904,10 +904,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
diff --git a/mm/memory.c b/mm/memory.c
index 6702c9187114..68d10a63276d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -5345,7 +5345,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;
 
diff --git a/mm/shmem.c b/mm/shmem.c
index 48312b7727a7..406617a1fab8 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1780,7 +1780,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,
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 09/10] mm: thp: always enable mTHP support
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (7 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 08/10] mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves() Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:47   ` David Hildenbrand (Red Hat)
  2025-11-06 21:28 ` [RFC 10/10] mm: thp: x86: cleanup PSE feature bit usage Luiz Capitulino
  2025-12-03 13:58 ` [RFC 00/10] mm: thp: always enable mTHP support Lorenzo Stoakes
  10 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

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.

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 mm/huge_memory.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 0f016ea7082d..4117833c53ef 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -115,6 +115,9 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
 	else
 		supported_orders = THP_ORDERS_ALL_FILE_DEFAULT;
 
+	if (!pgtable_has_pmd_leaves())
+		supported_orders &= ~BIT(PMD_ORDER);
+
 	orders &= supported_orders;
 	if (!orders)
 		return 0;
@@ -122,7 +125,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. */
@@ -805,6 +808,9 @@ 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())
+		orders &= ~BIT(PMD_ORDER);
+
 	order = highest_order(orders);
 	while (orders) {
 		thpsize = thpsize_create(order, *hugepage_kobj);
@@ -904,9 +910,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
 	 */
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC 10/10] mm: thp: x86: cleanup PSE feature bit usage
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (8 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 09/10] mm: thp: always enable mTHP support Luiz Capitulino
@ 2025-11-06 21:28 ` Luiz Capitulino
  2025-11-17 17:49   ` David Hildenbrand (Red Hat)
  2025-12-03 13:58 ` [RFC 00/10] mm: thp: always enable mTHP support Lorenzo Stoakes
  10 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-06 21:28 UTC (permalink / raw)
  To: david, linux-kernel, linux-mm; +Cc: ryan.roberts, akpm, lorenzo.stoakes

Historically, THP support on x86 checked the PSE feature bit to enable
THP. On 64-bit, this check is redundant since PSE is always enabled by
default for compatibility. On 32-bit, PSE enables 4MB page support and
must be checked. To clean this up, this commit:

1. Drops arch_has_pmd_leaves() from common x86 code. For 64-bit,
   we assume PMD-sized pages are always supported

2. Checks for PSE only on 32-bit, using arch_has_pmd_leaves()

Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
---
 arch/x86/include/asm/pgtable.h    | 6 ------
 arch/x86/include/asm/pgtable_32.h | 6 ++++++
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 08d109280e36..55b88de5178f 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -313,12 +313,6 @@ static inline int pud_trans_huge(pud_t pud)
 }
 #endif
 
-#define arch_has_pmd_leaves arch_has_pmd_leaves
-static inline int arch_has_pmd_leaves(void)
-{
-	return boot_cpu_has(X86_FEATURE_PSE);
-}
-
 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
 static inline bool pmd_special(pmd_t pmd)
 {
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index b612cc57a4d3..3bd51cfa431e 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -45,6 +45,12 @@ do {						\
 	flush_tlb_one_kernel((vaddr));		\
 } while (0)
 
+#define arch_has_pmd_leaves arch_has_pmd_leaves
+static inline int arch_has_pmd_leaves(void)
+{
+	return boot_cpu_has(X86_FEATURE_PSE);
+}
+
 #endif /* !__ASSEMBLER__ */
 
 /*
-- 
2.51.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 01/10] docs: tmpfs: remove implementation detail reference
  2025-11-06 21:28 ` [RFC 01/10] docs: tmpfs: remove implementation detail reference Luiz Capitulino
@ 2025-11-17 17:26   ` David Hildenbrand (Red Hat)
  0 siblings, 0 replies; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:26 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> 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.
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---

Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 03/10] drivers: dax: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 ` [RFC 03/10] drivers: dax: use pgtable_has_pmd_leaves() Luiz Capitulino
@ 2025-11-17 17:28   ` David Hildenbrand (Red Hat)
  0 siblings, 0 replies; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:28 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> dav_align_valid() uses has_transparent_hugepage() to check if PMD-sized
> pages are supported, use pgtable_has_pmd_leaves() instead.
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---
>   drivers/dax/dax-private.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h
> index 0867115aeef2..10aeaec9e789 100644
> --- a/drivers/dax/dax-private.h
> +++ b/drivers/dax/dax-private.h
> @@ -117,7 +117,7 @@ static inline bool dax_align_valid(unsigned long align)
>   {
>   	if (align == PUD_SIZE && IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD))

As discussed offlist, it would be great to later also have this be

if (align == PUD_SIZE && pgtable_has_pud_leaves()

Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 04/10] drivers: i915 selftest: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 ` [RFC 04/10] drivers: i915 selftest: " Luiz Capitulino
@ 2025-11-17 17:29   ` David Hildenbrand (Red Hat)
  2025-11-17 17:30   ` David Hildenbrand (Red Hat)
  1 sibling, 0 replies; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:29 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> igt_can_allocate_thp() uses has_transparente_hugepage() to check if
> PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
> 

Right, I think we really only care about PMDs here for now.

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 04/10] drivers: i915 selftest: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 ` [RFC 04/10] drivers: i915 selftest: " Luiz Capitulino
  2025-11-17 17:29   ` David Hildenbrand (Red Hat)
@ 2025-11-17 17:30   ` David Hildenbrand (Red Hat)
  2025-11-17 18:55     ` Luiz Capitulino
  1 sibling, 1 reply; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:30 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> igt_can_allocate_thp() uses has_transparente_hugepage() to check if
> PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---
>   drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> index bd08605a1611..c76aafa36d2b 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
> @@ -1316,7 +1316,7 @@ typedef struct drm_i915_gem_object *
>   
>   static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
>   {
> -	return i915->mm.gemfs && has_transparent_hugepage();
> +	return i915->mm.gemfs && pgtable_has_pmd_leaves();

On second thought, is it problematic that we might be losing the 
CONFIG_TRANSPARENT_HUGEPAGE check? Should we check for that separately?

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 05/10] drivers: nvdimm: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 ` [RFC 05/10] drivers: nvdimm: " Luiz Capitulino
@ 2025-11-17 17:32   ` David Hildenbrand (Red Hat)
  0 siblings, 0 replies; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:32 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> nd_pfn_supported_alignments() and nd_pfn_supported_alignments() use
> has_transparent_hugepage() to check if PMD-sized pages are supported,
> use pgtable_has_pmd_leaves() instead.
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---
>   drivers/nvdimm/pfn_devs.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
> index 42b172fc5576..989f87f07e0c 100644
> --- a/drivers/nvdimm/pfn_devs.c
> +++ b/drivers/nvdimm/pfn_devs.c
> @@ -94,7 +94,7 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)
>   
>   	alignments[0] = PAGE_SIZE;
>   
> -	if (has_transparent_hugepage()) {
> +	if (pgtable_has_pmd_leaves()) {
>   		alignments[1] = HPAGE_PMD_SIZE;
>   		if (has_transparent_pud_hugepage())

Yeah, that should become pgtable_has_pud_leaves() later.

>   			alignments[2] = HPAGE_PUD_SIZE;
> @@ -109,7 +109,7 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)
>   static unsigned long nd_pfn_default_alignment(void)
>   {
>   
> -	if (has_transparent_hugepage())
> +	if (pgtable_has_pmd_leaves())
>   		return HPAGE_PMD_SIZE;
>   	return PAGE_SIZE;
>   }

Similar question, what if the kernel would be built without 
CONFIG_TRANSPARENT_HUGEPAGE, would it matter here?

In that case, an additional eary "if 
(!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))" might do the trick.

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 06/10] mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
  2025-11-06 21:28 ` [RFC 06/10] mm: debug_vm_pgtable: " Luiz Capitulino
@ 2025-11-17 17:40   ` David Hildenbrand (Red Hat)
  2025-12-03 22:09     ` David Hildenbrand (Red Hat)
  0 siblings, 1 reply; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:40 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> debug_vm_pgtable calls has_transparent_hugepage() in multiple places to
> check if PMD-sized pages are supported, use pgtable_has_pmd_leaves()

Is that code even dealing with pages? Likely we really only want to 
check whether PMD leaves are supported, independent of any pages.

> instead.
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---
>   mm/debug_vm_pgtable.c | 20 ++++++++++----------
>   1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
> index 830107b6dd08..241b36c78ac9 100644
> --- a/mm/debug_vm_pgtable.c
> +++ b/mm/debug_vm_pgtable.c
> @@ -170,7 +170,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;


All of these are currently protected by CONFIG_TRANSPARENT_HUGEPAGE, right?

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves()
  2025-11-06 21:28 ` [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves() Luiz Capitulino
@ 2025-11-17 17:45   ` David Hildenbrand (Red Hat)
  2025-11-17 19:01     ` Luiz Capitulino
  0 siblings, 1 reply; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:45 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> Now that the majority of has_transparent_hugepage() callers have been
> converted to pgtable_has_pmd_leaves(), rename has_transparent_hugepage()
> to arch_has_pmd_leaves() since that's what the helper checks for.
> 
> arch_has_pmd_leaves() is supposed to be called only by
> init_arch_has_pmd_leaves(), except for two exeptions:
> 
> 1. shmem: shmem code runs very early during boot so it can't use
>     pgtable_has_pmd_leaves()

Can't we just initialize pgtable_has_pmd_leaves() earlier then?

> 2. hugepage_init(): just a temporary exception, this function will be
>     converted in a future commit
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---


[...]

> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index e4c5f70b0a01..02a2772ec548 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -2026,8 +2026,8 @@ static inline bool pgtable_has_pmd_leaves(void)
>   #endif
>   #endif
>   
> -#ifndef has_transparent_hugepage
> -#define has_transparent_hugepage() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
> +#ifndef arch_has_pmd_leaves
> +#define arch_has_pmd_leaves() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
>   #endif

Ah, so it stays for now only set with CONFIG_TRANSPARENT_HUGEPAGE. I 
guess that's something to sort out later :)


-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 09/10] mm: thp: always enable mTHP support
  2025-11-06 21:28 ` [RFC 09/10] mm: thp: always enable mTHP support Luiz Capitulino
@ 2025-11-17 17:47   ` David Hildenbrand (Red Hat)
  2025-11-17 19:14     ` Luiz Capitulino
  0 siblings, 1 reply; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:47 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino 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.
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---
>   mm/huge_memory.c | 11 +++++++----
>   1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 0f016ea7082d..4117833c53ef 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -115,6 +115,9 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
>   	else
>   		supported_orders = THP_ORDERS_ALL_FILE_DEFAULT;
>   
> +	if (!pgtable_has_pmd_leaves())
> +		supported_orders &= ~BIT(PMD_ORDER);
> +

Won't this leave PUD_ORDER set?

Ideally, later we'd also have a

if (!pgtable_has_pud_leaves())
	supported_orders &= ~BIT(PUD_ORDER);


For now you could simply clear PUD_ORDER for now as well.

No PMD leaves -> No PUD leaves, so clear them in all cases to not leave 
PUD_ORDER set.

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 10/10] mm: thp: x86: cleanup PSE feature bit usage
  2025-11-06 21:28 ` [RFC 10/10] mm: thp: x86: cleanup PSE feature bit usage Luiz Capitulino
@ 2025-11-17 17:49   ` David Hildenbrand (Red Hat)
  2025-11-17 19:15     ` Luiz Capitulino
  0 siblings, 1 reply; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-11-17 17:49 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 06.11.25 22:28, Luiz Capitulino wrote:
> Historically, THP support on x86 checked the PSE feature bit to enable
> THP. On 64-bit, this check is redundant since PSE is always enabled by
> default for compatibility. On 32-bit, PSE enables 4MB page support and

Or 2MB support with 4byte PTEs I guess?

> must be checked. To clean this up, this commit:
> 

Likely the subject should start with: "x86/mm:"


> 1. Drops arch_has_pmd_leaves() from common x86 code. For 64-bit,
>     we assume PMD-sized pages are always supported
> 
> 2. Checks for PSE only on 32-bit, using arch_has_pmd_leaves()
> 
> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
> ---
>   arch/x86/include/asm/pgtable.h    | 6 ------
>   arch/x86/include/asm/pgtable_32.h | 6 ++++++
>   2 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
> index 08d109280e36..55b88de5178f 100644
> --- a/arch/x86/include/asm/pgtable.h
> +++ b/arch/x86/include/asm/pgtable.h
> @@ -313,12 +313,6 @@ static inline int pud_trans_huge(pud_t pud)
>   }
>   #endif
>   
> -#define arch_has_pmd_leaves arch_has_pmd_leaves
> -static inline int arch_has_pmd_leaves(void)
> -{
> -	return boot_cpu_has(X86_FEATURE_PSE);
> -}
> -
>   #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
>   static inline bool pmd_special(pmd_t pmd)
>   {
> diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
> index b612cc57a4d3..3bd51cfa431e 100644
> --- a/arch/x86/include/asm/pgtable_32.h
> +++ b/arch/x86/include/asm/pgtable_32.h
> @@ -45,6 +45,12 @@ do {						\
>   	flush_tlb_one_kernel((vaddr));		\
>   } while (0)
>   
> +#define arch_has_pmd_leaves arch_has_pmd_leaves
> +static inline int arch_has_pmd_leaves(void)
> +{
> +	return boot_cpu_has(X86_FEATURE_PSE);
> +}
> +
>   #endif /* !__ASSEMBLER__ */
>   
>   /*

Right, IIUC 64bit should neve rrequire this check.

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 04/10] drivers: i915 selftest: use pgtable_has_pmd_leaves()
  2025-11-17 17:30   ` David Hildenbrand (Red Hat)
@ 2025-11-17 18:55     ` Luiz Capitulino
  2025-12-02 10:51       ` David Hildenbrand (Red Hat)
  0 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-17 18:55 UTC (permalink / raw)
  To: David Hildenbrand (Red Hat), linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 2025-11-17 12:30, David Hildenbrand (Red Hat) wrote:
> On 06.11.25 22:28, Luiz Capitulino wrote:
>> igt_can_allocate_thp() uses has_transparente_hugepage() to check if
>> PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
>>
>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>> ---
>>   drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>> index bd08605a1611..c76aafa36d2b 100644
>> --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>> @@ -1316,7 +1316,7 @@ typedef struct drm_i915_gem_object *
>>   static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
>>   {
>> -    return i915->mm.gemfs && has_transparent_hugepage();
>> +    return i915->mm.gemfs && pgtable_has_pmd_leaves();
> 
> On second thought, is it problematic that we might be losing the CONFIG_TRANSPARENT_HUGEPAGE check? Should we check for that separately?

That's a good point.

In this RFC, pgtable_has_pmd_leaves() should be functionally equivalent
to has_transparent_hugepage() so I think we're good. That beind said, I
also think that we should disentangle pgtable_has_pmd_leaves() from THP
now or in the future. When we do this the breakage you're spotting will
happen.

What about adding thp_has_pmd_support() which does:

   return IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && pgtable_has_pmd_leaves();

Then I can convert all the cases you spotted to thp_has_pmd_support().



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves()
  2025-11-17 17:45   ` David Hildenbrand (Red Hat)
@ 2025-11-17 19:01     ` Luiz Capitulino
  2025-12-02 10:53       ` David Hildenbrand (Red Hat)
  0 siblings, 1 reply; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-17 19:01 UTC (permalink / raw)
  To: David Hildenbrand (Red Hat), linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 2025-11-17 12:45, David Hildenbrand (Red Hat) wrote:
> On 06.11.25 22:28, Luiz Capitulino wrote:
>> Now that the majority of has_transparent_hugepage() callers have been
>> converted to pgtable_has_pmd_leaves(), rename has_transparent_hugepage()
>> to arch_has_pmd_leaves() since that's what the helper checks for.
>>
>> arch_has_pmd_leaves() is supposed to be called only by
>> init_arch_has_pmd_leaves(), except for two exeptions:
>>
>> 1. shmem: shmem code runs very early during boot so it can't use
>>     pgtable_has_pmd_leaves()
> 
> Can't we just initialize pgtable_has_pmd_leaves() earlier then?

I can look into doing that. When I worked on this RFC I wondered if
arch_has_pmd_leaves() (when implemented by the arch) could run so early
given that some (all?) archs check feature bits so they must be
available this early as well. But I'll check this, having
pgtable_has_pmd_leaves() being available as early as possible is
probably the right thing to do.

>> 2. hugepage_init(): just a temporary exception, this function will be
>>     converted in a future commit
>>
>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>> ---
> 
> 
> [...]
> 
>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>> index e4c5f70b0a01..02a2772ec548 100644
>> --- a/include/linux/pgtable.h
>> +++ b/include/linux/pgtable.h
>> @@ -2026,8 +2026,8 @@ static inline bool pgtable_has_pmd_leaves(void)
>>   #endif
>>   #endif
>> -#ifndef has_transparent_hugepage
>> -#define has_transparent_hugepage() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
>> +#ifndef arch_has_pmd_leaves
>> +#define arch_has_pmd_leaves() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
>>   #endif
> 
> Ah, so it stays for now only set with CONFIG_TRANSPARENT_HUGEPAGE. I guess that's something to sort out later :)

I suggested something we could do in this series. Also, I skipped
commenting on all the cases you spotted as I think they refer to the
same issue (please, do point out if you think I'm wrong).



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 09/10] mm: thp: always enable mTHP support
  2025-11-17 17:47   ` David Hildenbrand (Red Hat)
@ 2025-11-17 19:14     ` Luiz Capitulino
  0 siblings, 0 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-17 19:14 UTC (permalink / raw)
  To: David Hildenbrand (Red Hat), linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 2025-11-17 12:47, David Hildenbrand (Red Hat) wrote:
> On 06.11.25 22:28, Luiz Capitulino 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.
>>
>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>> ---
>>   mm/huge_memory.c | 11 +++++++----
>>   1 file changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
>> index 0f016ea7082d..4117833c53ef 100644
>> --- a/mm/huge_memory.c
>> +++ b/mm/huge_memory.c
>> @@ -115,6 +115,9 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
>>       else
>>           supported_orders = THP_ORDERS_ALL_FILE_DEFAULT;
>> +    if (!pgtable_has_pmd_leaves())
>> +        supported_orders &= ~BIT(PMD_ORDER);
>> +
> 
> Won't this leave PUD_ORDER set?
> 
> Ideally, later we'd also have a
> 
> if (!pgtable_has_pud_leaves())
>      supported_orders &= ~BIT(PUD_ORDER);
> 
> 
> For now you could simply clear PUD_ORDER for now as well.
> 
> No PMD leaves -> No PUD leaves, so clear them in all cases to not leave PUD_ORDER set.

OK, I'll do it.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 10/10] mm: thp: x86: cleanup PSE feature bit usage
  2025-11-17 17:49   ` David Hildenbrand (Red Hat)
@ 2025-11-17 19:15     ` Luiz Capitulino
  0 siblings, 0 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-11-17 19:15 UTC (permalink / raw)
  To: David Hildenbrand (Red Hat), linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 2025-11-17 12:49, David Hildenbrand (Red Hat) wrote:
> On 06.11.25 22:28, Luiz Capitulino wrote:
>> Historically, THP support on x86 checked the PSE feature bit to enable
>> THP. On 64-bit, this check is redundant since PSE is always enabled by
>> default for compatibility. On 32-bit, PSE enables 4MB page support and
> 
> Or 2MB support with 4byte PTEs I guess?
> 
>> must be checked. To clean this up, this commit:
>>
> 
> Likely the subject should start with: "x86/mm:"

You're right on both points. I'll fix the changelog for the next
version.

> 
> 
>> 1. Drops arch_has_pmd_leaves() from common x86 code. For 64-bit,
>>     we assume PMD-sized pages are always supported
>>
>> 2. Checks for PSE only on 32-bit, using arch_has_pmd_leaves()
>>
>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>> ---
>>   arch/x86/include/asm/pgtable.h    | 6 ------
>>   arch/x86/include/asm/pgtable_32.h | 6 ++++++
>>   2 files changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
>> index 08d109280e36..55b88de5178f 100644
>> --- a/arch/x86/include/asm/pgtable.h
>> +++ b/arch/x86/include/asm/pgtable.h
>> @@ -313,12 +313,6 @@ static inline int pud_trans_huge(pud_t pud)
>>   }
>>   #endif
>> -#define arch_has_pmd_leaves arch_has_pmd_leaves
>> -static inline int arch_has_pmd_leaves(void)
>> -{
>> -    return boot_cpu_has(X86_FEATURE_PSE);
>> -}
>> -
>>   #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
>>   static inline bool pmd_special(pmd_t pmd)
>>   {
>> diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
>> index b612cc57a4d3..3bd51cfa431e 100644
>> --- a/arch/x86/include/asm/pgtable_32.h
>> +++ b/arch/x86/include/asm/pgtable_32.h
>> @@ -45,6 +45,12 @@ do {                        \
>>       flush_tlb_one_kernel((vaddr));        \
>>   } while (0)
>> +#define arch_has_pmd_leaves arch_has_pmd_leaves
>> +static inline int arch_has_pmd_leaves(void)
>> +{
>> +    return boot_cpu_has(X86_FEATURE_PSE);
>> +}
>> +
>>   #endif /* !__ASSEMBLER__ */
>>   /*
> 
> Right, IIUC 64bit should neve rrequire this check.
> 



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 04/10] drivers: i915 selftest: use pgtable_has_pmd_leaves()
  2025-11-17 18:55     ` Luiz Capitulino
@ 2025-12-02 10:51       ` David Hildenbrand (Red Hat)
  2025-12-03 13:19         ` Luiz Capitulino
  0 siblings, 1 reply; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-12-02 10:51 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 11/17/25 19:55, Luiz Capitulino wrote:
> On 2025-11-17 12:30, David Hildenbrand (Red Hat) wrote:
>> On 06.11.25 22:28, Luiz Capitulino wrote:
>>> igt_can_allocate_thp() uses has_transparente_hugepage() to check if
>>> PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
>>>
>>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>>> ---
>>>    drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +-
>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>>> index bd08605a1611..c76aafa36d2b 100644
>>> --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>>> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>>> @@ -1316,7 +1316,7 @@ typedef struct drm_i915_gem_object *
>>>    static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
>>>    {
>>> -    return i915->mm.gemfs && has_transparent_hugepage();
>>> +    return i915->mm.gemfs && pgtable_has_pmd_leaves();
>>
>> On second thought, is it problematic that we might be losing the CONFIG_TRANSPARENT_HUGEPAGE check? Should we check for that separately?
> 
> That's a good point.
> 
> In this RFC, pgtable_has_pmd_leaves() should be functionally equivalent
> to has_transparent_hugepage() so I think we're good. That beind said, I
> also think that we should disentangle pgtable_has_pmd_leaves() from THP
> now or in the future. When we do this the breakage you're spotting will
> happen.
> 
> What about adding thp_has_pmd_support() which does:
> 
>     return IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && pgtable_has_pmd_leaves();
> 
> Then I can convert all the cases you spotted to thp_has_pmd_support().

I hope we can avoid such a wrapper for the time being. Maybe we can just 
keep pgtable_has_pmd_leaves() glued to CONFIG_TRANSPARENT_HUGEPAGE for 
now, and leave untangling that for the next cleanup?

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves()
  2025-11-17 19:01     ` Luiz Capitulino
@ 2025-12-02 10:53       ` David Hildenbrand (Red Hat)
  0 siblings, 0 replies; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-12-02 10:53 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 11/17/25 20:01, Luiz Capitulino wrote:
> On 2025-11-17 12:45, David Hildenbrand (Red Hat) wrote:
>> On 06.11.25 22:28, Luiz Capitulino wrote:
>>> Now that the majority of has_transparent_hugepage() callers have been
>>> converted to pgtable_has_pmd_leaves(), rename has_transparent_hugepage()
>>> to arch_has_pmd_leaves() since that's what the helper checks for.
>>>
>>> arch_has_pmd_leaves() is supposed to be called only by
>>> init_arch_has_pmd_leaves(), except for two exeptions:
>>>
>>> 1. shmem: shmem code runs very early during boot so it can't use
>>>      pgtable_has_pmd_leaves()
>>
>> Can't we just initialize pgtable_has_pmd_leaves() earlier then?
> 
> I can look into doing that. When I worked on this RFC I wondered if
> arch_has_pmd_leaves() (when implemented by the arch) could run so early
> given that some (all?) archs check feature bits so they must be
> available this early as well. But I'll check this, having
> pgtable_has_pmd_leaves() being available as early as possible is
> probably the right thing to do.
> 
>>> 2. hugepage_init(): just a temporary exception, this function will be
>>>      converted in a future commit
>>>
>>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>>> ---
>>
>>
>> [...]
>>
>>> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
>>> index e4c5f70b0a01..02a2772ec548 100644
>>> --- a/include/linux/pgtable.h
>>> +++ b/include/linux/pgtable.h
>>> @@ -2026,8 +2026,8 @@ static inline bool pgtable_has_pmd_leaves(void)
>>>    #endif
>>>    #endif
>>> -#ifndef has_transparent_hugepage
>>> -#define has_transparent_hugepage() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
>>> +#ifndef arch_has_pmd_leaves
>>> +#define arch_has_pmd_leaves() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
>>>    #endif
>>
>> Ah, so it stays for now only set with CONFIG_TRANSPARENT_HUGEPAGE. I guess that's something to sort out later :)
> 
> I suggested something we could do in this series. Also, I skipped
> commenting on all the cases you spotted as I think they refer to the
> same issue (please, do point out if you think I'm wrong).

Right. If we keep PMD-leave support glue to CONFIG_TRANSPARENT_HUGEPAGE 
in this series, could we also simplify patch #2, to have it reside in 
mm/huge_memory.c ?

Then, it's clearer that it is still glued to CONFIG_TRANSPARENT_HUGEPAGE.

-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 04/10] drivers: i915 selftest: use pgtable_has_pmd_leaves()
  2025-12-02 10:51       ` David Hildenbrand (Red Hat)
@ 2025-12-03 13:19         ` Luiz Capitulino
  0 siblings, 0 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-12-03 13:19 UTC (permalink / raw)
  To: David Hildenbrand (Red Hat), linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 2025-12-02 05:51, David Hildenbrand (Red Hat) wrote:
> On 11/17/25 19:55, Luiz Capitulino wrote:
>> On 2025-11-17 12:30, David Hildenbrand (Red Hat) wrote:
>>> On 06.11.25 22:28, Luiz Capitulino wrote:
>>>> igt_can_allocate_thp() uses has_transparente_hugepage() to check if
>>>> PMD-sized pages are supported, use pgtable_has_pmd_leaves() instead.
>>>>
>>>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>>>> ---
>>>>    drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 2 +-
>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>>>> index bd08605a1611..c76aafa36d2b 100644
>>>> --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>>>> +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
>>>> @@ -1316,7 +1316,7 @@ typedef struct drm_i915_gem_object *
>>>>    static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
>>>>    {
>>>> -    return i915->mm.gemfs && has_transparent_hugepage();
>>>> +    return i915->mm.gemfs && pgtable_has_pmd_leaves();
>>>
>>> On second thought, is it problematic that we might be losing the CONFIG_TRANSPARENT_HUGEPAGE check? Should we check for that separately?
>>
>> That's a good point.
>>
>> In this RFC, pgtable_has_pmd_leaves() should be functionally equivalent
>> to has_transparent_hugepage() so I think we're good. That beind said, I
>> also think that we should disentangle pgtable_has_pmd_leaves() from THP
>> now or in the future. When we do this the breakage you're spotting will
>> happen.
>>
>> What about adding thp_has_pmd_support() which does:
>>
>>     return IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && pgtable_has_pmd_leaves();
>>
>> Then I can convert all the cases you spotted to thp_has_pmd_support().
> 
> I hope we can avoid such a wrapper for the time being. Maybe we can just keep pgtable_has_pmd_leaves() glued to CONFIG_TRANSPARENT_HUGEPAGE for now, and leave untangling that for the next cleanup?

OK, I can do that in the v1 posting.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 00/10] mm: thp: always enable mTHP support
  2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
                   ` (9 preceding siblings ...)
  2025-11-06 21:28 ` [RFC 10/10] mm: thp: x86: cleanup PSE feature bit usage Luiz Capitulino
@ 2025-12-03 13:58 ` Lorenzo Stoakes
  2025-12-03 18:41   ` Luiz Capitulino
  10 siblings, 1 reply; 30+ messages in thread
From: Lorenzo Stoakes @ 2025-12-03 13:58 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: david, linux-kernel, linux-mm, ryan.roberts, akpm

Sorry I didn't say at the time - thanks, I do plan to look through this at
some point :)

Cheers, Lorenzo

On Thu, Nov 06, 2025 at 04:28:47PM -0500, Luiz Capitulino wrote:
> 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 support. In addition, the kernel lacks a well defined API to check for
> PMD-sized page support. It currently relies on has_transparent_hugepage()
> and thp_disabled_by_hw(), but they are not well defined and are tied to
> THP support.
>
> This series addresses both issues by introducing a new well defined API
> to query PMD-sized page support: pgtable_has_pmd_leaves(). Using this
> new helper, we ensure that mTHP remains enabled even when the
> architecture or CPU doesn't support PMD-sized pages.
>
> An important detail is that we need to do the same refactoring for
> has_transparent_pud_hugepage(). I actually have patches for this one
> too, I'm not including them here because I want to get some initial
> feedback on the general approach first (and maybe it's better to
> do that in a separate series).
>
> Thanks to David Hildenbrand for suggesting this improvement and for
> providing guidance (all bugs and misconcentpions are mine).
>
> Luiz Capitulino (10):
>   docs: tmpfs: remove implementation detail reference
>   mm: introduce pgtable_has_pmd_leaves()
>   drivers: dax: use pgtable_has_pmd_leaves()
>   drivers: i915 selftest: use pgtable_has_pmd_leaves()
>   drivers: nvdimm: use pgtable_has_pmd_leaves()
>   mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
>   treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves()
>   mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves()
>   mm: thp: always enable mTHP support
>   mm: thp: x86: cleanup PSE feature bit usage
>
>  Documentation/filesystems/tmpfs.rst           |  5 ++---
>  arch/mips/include/asm/pgtable.h               |  4 ++--
>  arch/mips/mm/tlb-r4k.c                        |  4 ++--
>  arch/powerpc/include/asm/book3s/64/hash-4k.h  |  2 +-
>  arch/powerpc/include/asm/book3s/64/hash-64k.h |  2 +-
>  arch/powerpc/include/asm/book3s/64/pgtable.h  | 10 +++++-----
>  arch/powerpc/include/asm/book3s/64/radix.h    |  2 +-
>  arch/powerpc/mm/book3s64/hash_pgtable.c       |  4 ++--
>  arch/s390/include/asm/pgtable.h               |  4 ++--
>  arch/x86/include/asm/pgtable.h                |  6 ------
>  arch/x86/include/asm/pgtable_32.h             |  6 ++++++
>  drivers/dax/dax-private.h                     |  2 +-
>  .../gpu/drm/i915/gem/selftests/huge_pages.c   |  2 +-
>  drivers/nvdimm/pfn_devs.c                     |  4 ++--
>  include/linux/huge_mm.h                       |  7 -------
>  include/linux/pgtable.h                       | 14 +++++++++++--
>  mm/debug_vm_pgtable.c                         | 20 +++++++++----------
>  mm/huge_memory.c                              | 13 ++++++------
>  mm/memory.c                                   | 12 ++++++++++-
>  mm/shmem.c                                    |  8 ++++----
>  20 files changed, 72 insertions(+), 59 deletions(-)
>
> --
> 2.51.1
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 00/10] mm: thp: always enable mTHP support
  2025-12-03 13:58 ` [RFC 00/10] mm: thp: always enable mTHP support Lorenzo Stoakes
@ 2025-12-03 18:41   ` Luiz Capitulino
  0 siblings, 0 replies; 30+ messages in thread
From: Luiz Capitulino @ 2025-12-03 18:41 UTC (permalink / raw)
  To: Lorenzo Stoakes; +Cc: david, linux-kernel, linux-mm, ryan.roberts, akpm

On 2025-12-03 08:58, Lorenzo Stoakes wrote:
> Sorry I didn't say at the time - thanks, I do plan to look through this at
> some point :)

Oh, thanks for letting me know. I appreciate that!

I assumed reviewers are waiting for v1, esp. after David's review.

PS: I hope I'll be able to send v1 in the next few weeks, but I can't
guarantee it.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC 06/10] mm: debug_vm_pgtable: use pgtable_has_pmd_leaves()
  2025-11-17 17:40   ` David Hildenbrand (Red Hat)
@ 2025-12-03 22:09     ` David Hildenbrand (Red Hat)
  0 siblings, 0 replies; 30+ messages in thread
From: David Hildenbrand (Red Hat) @ 2025-12-03 22:09 UTC (permalink / raw)
  To: Luiz Capitulino, linux-kernel, linux-mm
  Cc: ryan.roberts, akpm, lorenzo.stoakes

On 11/17/25 18:40, David Hildenbrand (Red Hat) wrote:
> On 06.11.25 22:28, Luiz Capitulino wrote:
>> debug_vm_pgtable calls has_transparent_hugepage() in multiple places to
>> check if PMD-sized pages are supported, use pgtable_has_pmd_leaves()
> 
> Is that code even dealing with pages? Likely we really only want to
> check whether PMD leaves are supported, independent of any pages.

I recall that some arch protect certain pmd_* helpers under 
CONFIG_TRANSPARENT_HUGEPAGE.

But it's certainly something to explore, to see if we can just get rid 
of that without causing compile-time or runtime issues.

> 
>> instead.
>>
>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>> ---
>>    mm/debug_vm_pgtable.c | 20 ++++++++++----------
>>    1 file changed, 10 insertions(+), 10 deletions(-)
>>
>> diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
>> index 830107b6dd08..241b36c78ac9 100644
>> --- a/mm/debug_vm_pgtable.c
>> +++ b/mm/debug_vm_pgtable.c
>> @@ -170,7 +170,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;
> 
> 
> All of these are currently protected by CONFIG_TRANSPARENT_HUGEPAGE, right?

IIUC, yes.


-- 
Cheers

David


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2025-12-03 22:09 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-06 21:28 [RFC 00/10] mm: thp: always enable mTHP support Luiz Capitulino
2025-11-06 21:28 ` [RFC 01/10] docs: tmpfs: remove implementation detail reference Luiz Capitulino
2025-11-17 17:26   ` David Hildenbrand (Red Hat)
2025-11-06 21:28 ` [RFC 02/10] mm: introduce pgtable_has_pmd_leaves() Luiz Capitulino
2025-11-06 21:28 ` [RFC 03/10] drivers: dax: use pgtable_has_pmd_leaves() Luiz Capitulino
2025-11-17 17:28   ` David Hildenbrand (Red Hat)
2025-11-06 21:28 ` [RFC 04/10] drivers: i915 selftest: " Luiz Capitulino
2025-11-17 17:29   ` David Hildenbrand (Red Hat)
2025-11-17 17:30   ` David Hildenbrand (Red Hat)
2025-11-17 18:55     ` Luiz Capitulino
2025-12-02 10:51       ` David Hildenbrand (Red Hat)
2025-12-03 13:19         ` Luiz Capitulino
2025-11-06 21:28 ` [RFC 05/10] drivers: nvdimm: " Luiz Capitulino
2025-11-17 17:32   ` David Hildenbrand (Red Hat)
2025-11-06 21:28 ` [RFC 06/10] mm: debug_vm_pgtable: " Luiz Capitulino
2025-11-17 17:40   ` David Hildenbrand (Red Hat)
2025-12-03 22:09     ` David Hildenbrand (Red Hat)
2025-11-06 21:28 ` [RFC 07/10] treewide: rename has_transparent_hugepage() to arch_has_pmd_leaves() Luiz Capitulino
2025-11-17 17:45   ` David Hildenbrand (Red Hat)
2025-11-17 19:01     ` Luiz Capitulino
2025-12-02 10:53       ` David Hildenbrand (Red Hat)
2025-11-06 21:28 ` [RFC 08/10] mm: replace thp_disabled_by_hw() with pgtable_has_pmd_leaves() Luiz Capitulino
2025-11-06 21:28 ` [RFC 09/10] mm: thp: always enable mTHP support Luiz Capitulino
2025-11-17 17:47   ` David Hildenbrand (Red Hat)
2025-11-17 19:14     ` Luiz Capitulino
2025-11-06 21:28 ` [RFC 10/10] mm: thp: x86: cleanup PSE feature bit usage Luiz Capitulino
2025-11-17 17:49   ` David Hildenbrand (Red Hat)
2025-11-17 19:15     ` Luiz Capitulino
2025-12-03 13:58 ` [RFC 00/10] mm: thp: always enable mTHP support Lorenzo Stoakes
2025-12-03 18:41   ` Luiz Capitulino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox