AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/25 06:00 flow patch-triage
1m Args:
null

Results:
{
  "EnableConfigs": [
    "TRANSPARENT_HUGEPAGE"
  ],
  "FocusSymbols": [
    "__thp_vma_allowable_orders",
    "shmem_allowable_huge_orders",
    "do_set_pmd"
  ],
  "Reasoning": "The patch modifies how THP support is checked and initialized, replacing `has_transparent_hugepage()` with `pgtable_has_pmd_leaves()`. It modifies core MM logic (THP, shmem, dax, nvdimm) to filter out PMD and PUD orders if the CPU does not support PMD leaves. This is functional and reachable.",
  "WorthFuzzing": true
}

1/1 2026/07/25 06:00 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 8fd6564930b5838559c30d51d8a0a6ee87c25203\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Sat Jul 25 06:00:13 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/Documentation/filesystems/tmpfs.rst b/Documentation/filesystems/tmpfs.rst\nindex d677e0428c3f68..46fc986c3388ac 100644\n--- a/Documentation/filesystems/tmpfs.rst\n+++ b/Documentation/filesystems/tmpfs.rst\n@@ -109,9 +109,8 @@ noswap  Disables swap. Remounts must respect the original settings.\n ======  ===========================================================\n \n tmpfs also supports Transparent Huge Pages which requires a kernel\n-configured with CONFIG_TRANSPARENT_HUGEPAGE and with huge supported for\n-your system (has_transparent_hugepage(), which is architecture specific).\n-The mount options for this are:\n+configured with CONFIG_TRANSPARENT_HUGEPAGE and with huge pages\n+supported for your system. The mount options for this are:\n \n ================ ==============================================================\n huge=never       Do not allocate huge pages.  This is the default.\ndiff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h\nindex fa7b935f947ca0..2a0a7ddf8bee7e 100644\n--- a/arch/mips/include/asm/pgtable.h\n+++ b/arch/mips/include/asm/pgtable.h\n@@ -615,9 +615,6 @@ unsigned long io_remap_pfn_range_pfn(unsigned long pfn, unsigned long size);\n /* We don't have hardware dirty/accessed bits, generic_pmdp_establish is fine.*/\n #define pmdp_establish generic_pmdp_establish\n \n-#define has_transparent_hugepage has_transparent_hugepage\n-extern int has_transparent_hugepage(void);\n-\n static inline int pmd_trans_huge(pmd_t pmd)\n {\n \treturn !!(pmd_val(pmd) \u0026 _PAGE_HUGE);\n@@ -743,6 +740,9 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,\n \n #endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n \n+#define arch_has_pmd_leaves arch_has_pmd_leaves\n+extern int arch_has_pmd_leaves(void);\n+\n #ifdef _PAGE_HUGE\n #define pmd_leaf(pmd)\t((pmd_val(pmd) \u0026 _PAGE_HUGE) != 0)\n #define pud_leaf(pud)\t((pud_val(pud) \u0026 _PAGE_HUGE) != 0)\ndiff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c\nindex 24fe85fa169d16..9339ebb0815f23 100644\n--- a/arch/mips/mm/tlb-r4k.c\n+++ b/arch/mips/mm/tlb-r4k.c\n@@ -432,9 +432,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,\n #endif\n }\n \n-#ifdef CONFIG_TRANSPARENT_HUGEPAGE\n-\n-int has_transparent_hugepage(void)\n+int arch_has_pmd_leaves(void)\n {\n \tstatic unsigned int mask = -1;\n \n@@ -450,9 +448,7 @@ int has_transparent_hugepage(void)\n \t}\n \treturn mask == PM_HUGE_MASK;\n }\n-EXPORT_SYMBOL(has_transparent_hugepage);\n-\n-#endif /* CONFIG_TRANSPARENT_HUGEPAGE  */\n+EXPORT_SYMBOL(arch_has_pmd_leaves);\n \n /*\n  * Used for loading TLB entries before trap_init() has started, when we\ndiff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h\nindex 8e5bd9902bed4e..d532e3f0dfc3b1 100644\n--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h\n+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h\n@@ -165,9 +165,9 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,\n extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);\n extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,\n \t\t\t\t       unsigned long addr, pmd_t *pmdp);\n-extern int hash__has_transparent_hugepage(void);\n #endif\n \n+extern int hash__arch_has_pmd_leaves(void);\n #endif /* !__ASSEMBLER__ */\n \n #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */\ndiff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h\nindex 7deb3a66890bcd..d523c80f44f717 100644\n--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h\n+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h\n@@ -278,9 +278,9 @@ extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,\n extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);\n extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,\n \t\t\t\t       unsigned long addr, pmd_t *pmdp);\n-extern int hash__has_transparent_hugepage(void);\n #endif /*  CONFIG_TRANSPARENT_HUGEPAGE */\n \n+extern int hash__arch_has_pmd_leaves(void);\n #endif\t/* __ASSEMBLER__ */\n \n #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */\ndiff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h\nindex f4db7d7fbd5c62..41166d44fa756e 100644\n--- a/arch/powerpc/include/asm/book3s/64/pgtable.h\n+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h\n@@ -1121,15 +1121,6 @@ static inline void update_mmu_cache_pud(struct vm_area_struct *vma,\n {\n }\n \n-extern int hash__has_transparent_hugepage(void);\n-static inline int has_transparent_hugepage(void)\n-{\n-\tif (radix_enabled())\n-\t\treturn radix__has_transparent_hugepage();\n-\treturn hash__has_transparent_hugepage();\n-}\n-#define has_transparent_hugepage has_transparent_hugepage\n-\n static inline int has_transparent_pud_hugepage(void)\n {\n \tif (radix_enabled())\n@@ -1441,6 +1432,15 @@ static inline bool arch_needs_pgtable_deposit(void)\n \n #endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n \n+extern int hash__arch_has_pmd_leaves(void);\n+static inline int arch_has_pmd_leaves(void)\n+{\n+\tif (radix_enabled())\n+\t\treturn radix__arch_has_pmd_leaves();\n+\treturn hash__arch_has_pmd_leaves();\n+}\n+#define arch_has_pmd_leaves arch_has_pmd_leaves\n+\n #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION\n pte_t ptep_modify_prot_start(struct vm_area_struct *, unsigned long, pte_t *);\n void ptep_modify_prot_commit(struct vm_area_struct *, unsigned long,\ndiff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h\nindex da954e7797441f..e8b74528953fdc 100644\n--- a/arch/powerpc/include/asm/book3s/64/radix.h\n+++ b/arch/powerpc/include/asm/book3s/64/radix.h\n@@ -298,22 +298,22 @@ extern pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm,\n pud_t radix__pudp_huge_get_and_clear(struct mm_struct *mm,\n \t\t\t\t     unsigned long addr, pud_t *pudp);\n \n-static inline int radix__has_transparent_hugepage(void)\n+static inline int radix__has_transparent_pud_hugepage(void)\n {\n-\t/* For radix 2M at PMD level means thp */\n-\tif (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT)\n+\t/* For radix 1G at PUD level means pud hugepage support */\n+\tif (mmu_psize_defs[MMU_PAGE_1G].shift == PUD_SHIFT)\n \t\treturn 1;\n \treturn 0;\n }\n+#endif\n \n-static inline int radix__has_transparent_pud_hugepage(void)\n+static inline int radix__arch_has_pmd_leaves(void)\n {\n-\t/* For radix 1G at PUD level means pud hugepage support */\n-\tif (mmu_psize_defs[MMU_PAGE_1G].shift == PUD_SHIFT)\n+\t/* For radix 2M at PMD level means thp */\n+\tif (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT)\n \t\treturn 1;\n \treturn 0;\n }\n-#endif\n \n struct vmem_altmap;\n struct dev_pagemap;\ndiff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c\nindex d9b5b751d7b75b..a67bc1723404c2 100644\n--- a/arch/powerpc/mm/book3s64/hash_pgtable.c\n+++ b/arch/powerpc/mm/book3s64/hash_pgtable.c\n@@ -391,7 +391,9 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,\n \treturn old_pmd;\n }\n \n-int hash__has_transparent_hugepage(void)\n+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n+\n+int hash__arch_has_pmd_leaves(void)\n {\n \n \tif (!mmu_has_feature(MMU_FTR_16M_PAGE))\n@@ -420,9 +422,7 @@ int hash__has_transparent_hugepage(void)\n \n \treturn 1;\n }\n-EXPORT_SYMBOL_GPL(hash__has_transparent_hugepage);\n-\n-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n+EXPORT_SYMBOL_GPL(hash__arch_has_pmd_leaves);\n \n #ifdef CONFIG_STRICT_KERNEL_RWX\n \ndiff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h\nindex e882663a58e776..24ee90c7e9bf6b 100644\n--- a/arch/s390/include/asm/pgtable.h\n+++ b/arch/s390/include/asm/pgtable.h\n@@ -1825,13 +1825,13 @@ static inline int pmd_trans_huge(pmd_t pmd)\n {\n \treturn pmd_leaf(pmd);\n }\n+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n \n-#define has_transparent_hugepage has_transparent_hugepage\n-static inline int has_transparent_hugepage(void)\n+#define arch_has_pmd_leaves arch_has_pmd_leaves\n+static inline int arch_has_pmd_leaves(void)\n {\n \treturn cpu_has_edat1() ? 1 : 0;\n }\n-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n \n #ifdef CONFIG_PAGE_TABLE_CHECK\n static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)\ndiff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h\nindex 8e0018fadd14e6..3c6a641e6c211d 100644\n--- a/arch/x86/include/asm/pgtable.h\n+++ b/arch/x86/include/asm/pgtable.h\n@@ -306,12 +306,6 @@ static inline int pud_trans_huge(pud_t pud)\n }\n #endif\n \n-#define has_transparent_hugepage has_transparent_hugepage\n-static inline int has_transparent_hugepage(void)\n-{\n-\treturn boot_cpu_has(X86_FEATURE_PSE);\n-}\n-\n #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP\n static inline bool pmd_special(pmd_t pmd)\n {\n@@ -337,6 +331,12 @@ static inline pud_t pud_mkspecial(pud_t pud)\n #endif\t/* CONFIG_ARCH_SUPPORTS_PUD_PFNMAP */\n #endif /* CONFIG_TRANSPARENT_HUGEPAGE */\n \n+#define arch_has_pmd_leaves arch_has_pmd_leaves\n+static inline int arch_has_pmd_leaves(void)\n+{\n+\treturn boot_cpu_has(X86_FEATURE_PSE);\n+}\n+\n static inline pte_t pte_set_flags(pte_t pte, pteval_t set)\n {\n \tpteval_t v = native_pte_val(pte);\ndiff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h\nindex 81e4af49e39c10..35744ff6592ac9 100644\n--- a/drivers/dax/dax-private.h\n+++ b/drivers/dax/dax-private.h\n@@ -123,7 +123,7 @@ static inline bool dax_align_valid(unsigned long align)\n {\n \tif (align == PUD_SIZE \u0026\u0026 IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD))\n \t\treturn true;\n-\tif (align == PMD_SIZE \u0026\u0026 has_transparent_hugepage())\n+\tif (align == PMD_SIZE \u0026\u0026 pgtable_has_pmd_leaves())\n \t\treturn true;\n \tif (align == PAGE_SIZE)\n \t\treturn true;\ndiff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c\nindex 8fa9c16aba7ea0..457eb54e7ab6fc 100644\n--- a/drivers/nvdimm/pfn_devs.c\n+++ b/drivers/nvdimm/pfn_devs.c\n@@ -94,7 +94,8 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)\n \n \talignments[0] = PAGE_SIZE;\n \n-\tif (has_transparent_hugepage()) {\n+\tif (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026\n+\t    pgtable_has_pmd_leaves()) {\n \t\talignments[1] = HPAGE_PMD_SIZE;\n \t\tif (has_transparent_pud_hugepage())\n \t\t\talignments[2] = HPAGE_PUD_SIZE;\n@@ -109,7 +110,8 @@ static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)\n static unsigned long nd_pfn_default_alignment(void)\n {\n \n-\tif (has_transparent_hugepage())\n+\tif (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026\n+\t    pgtable_has_pmd_leaves())\n \t\treturn HPAGE_PMD_SIZE;\n \treturn PAGE_SIZE;\n }\ndiff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h\nindex c745f7ad22987f..525acea2eb59cb 100644\n--- a/include/linux/huge_mm.h\n+++ b/include/linux/huge_mm.h\n@@ -47,7 +47,6 @@ vm_fault_t vmf_insert_folio_pud(struct vm_fault *vmf, struct folio *folio,\n \t\t\t\tbool write);\n \n enum transparent_hugepage_flag {\n-\tTRANSPARENT_HUGEPAGE_UNSUPPORTED,\n \tTRANSPARENT_HUGEPAGE_FLAG,\n \tTRANSPARENT_HUGEPAGE_REQ_MADV_FLAG,\n \tTRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG,\n@@ -383,12 +382,6 @@ static inline bool vma_thp_disabled(struct vm_area_struct *vma,\n \treturn mm_flags_test(MMF_DISABLE_THP_EXCEPT_ADVISED, vma-\u003evm_mm);\n }\n \n-static inline bool thp_disabled_by_hw(void)\n-{\n-\t/* If the hardware/firmware marked hugepage support disabled. */\n-\treturn transparent_hugepage_flags \u0026 (1 \u003c\u003c TRANSPARENT_HUGEPAGE_UNSUPPORTED);\n-}\n-\n unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,\n \t\tunsigned long len, unsigned long pgoff, unsigned long flags);\n unsigned long thp_get_unmapped_area_vmaflags(struct file *filp, unsigned long addr,\ndiff --git a/include/linux/pgtable.h b/include/linux/pgtable.h\nindex 8c093c119e5a82..d571d161a84b3c 100644\n--- a/include/linux/pgtable.h\n+++ b/include/linux/pgtable.h\n@@ -14,6 +14,7 @@\n #include \u003clinux/mm_types.h\u003e\n #include \u003clinux/bug.h\u003e\n #include \u003clinux/errno.h\u003e\n+#include \u003clinux/jump_label.h\u003e\n #include \u003casm-generic/pgtable_uffd.h\u003e\n #include \u003clinux/page_table_check.h\u003e\n \n@@ -2313,6 +2314,21 @@ static inline const char *pgtable_level_to_str(enum pgtable_level level)\n \t}\n }\n \n+#ifdef CONFIG_MMU\n+DECLARE_STATIC_KEY_TRUE(__arch_has_pmd_leaves_key);\n+static inline bool pgtable_has_pmd_leaves(void)\n+{\n+\treturn static_branch_likely(\u0026__arch_has_pmd_leaves_key);\n+}\n+void __init pgtable_leaf_support_init(void);\n+#else\n+static inline bool pgtable_has_pmd_leaves(void)\n+{\n+\treturn false;\n+}\n+static inline void __init pgtable_leaf_support_init(void) { }\n+#endif\n+\n #endif /* !__ASSEMBLER__ */\n \n #if !defined(MAX_POSSIBLE_PHYSMEM_BITS) \u0026\u0026 !defined(CONFIG_64BIT)\n@@ -2328,8 +2344,8 @@ static inline const char *pgtable_level_to_str(enum pgtable_level level)\n #endif\n #endif\n \n-#ifndef has_transparent_hugepage\n-#define has_transparent_hugepage() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)\n+#ifndef arch_has_pmd_leaves\n+#define arch_has_pmd_leaves() IS_BUILTIN(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE)\n #endif\n \n #ifndef has_transparent_pud_hugepage\ndiff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c\nindex 2875fd22d7bb02..25038b74c7bc67 100644\n--- a/mm/debug_vm_pgtable.c\n+++ b/mm/debug_vm_pgtable.c\n@@ -177,7 +177,7 @@ static void __init pmd_basic_tests(struct pgtable_debug_args *args, int idx)\n \tunsigned long val = idx, *ptr = \u0026val;\n \tpmd_t pmd;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpr_debug(\"Validating PMD basic (%pGv)\\n\", ptr);\n@@ -222,7 +222,7 @@ static void __init pmd_advanced_tests(struct pgtable_debug_args *args)\n \tpmd_t pmd;\n \tunsigned long vaddr = args-\u003evaddr;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpage = (args-\u003epmd_pfn != ULONG_MAX) ? pfn_to_page(args-\u003epmd_pfn) : NULL;\n@@ -283,7 +283,7 @@ static void __init pmd_leaf_tests(struct pgtable_debug_args *args)\n {\n \tpmd_t pmd;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpr_debug(\"Validating PMD leaf\\n\");\n@@ -688,7 +688,7 @@ static void __init pmd_protnone_tests(struct pgtable_debug_args *args)\n \tif (!IS_ENABLED(CONFIG_ARCH_HAS_PTE_PROTNONE))\n \t\treturn;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpr_debug(\"Validating PMD protnone\\n\");\n@@ -737,7 +737,7 @@ static void __init pmd_soft_dirty_tests(struct pgtable_debug_args *args)\n \tif (!pgtable_supports_soft_dirty())\n \t\treturn;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpr_debug(\"Validating PMD soft dirty\\n\");\n@@ -754,7 +754,7 @@ static void __init pmd_leaf_soft_dirty_tests(struct pgtable_debug_args *args)\n \t    !IS_ENABLED(CONFIG_ARCH_HAS_PMD_SOFTLEAVES))\n \t\treturn;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpr_debug(\"Validating PMD swap soft dirty\\n\");\n@@ -825,7 +825,7 @@ static void __init pmd_softleaf_tests(struct pgtable_debug_args *args)\n \tswp_entry_t arch_entry;\n \tpmd_t pmd1, pmd2;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpr_debug(\"Validating PMD swap\\n\");\n@@ -906,7 +906,7 @@ static void __init pmd_thp_tests(struct pgtable_debug_args *args)\n {\n \tpmd_t pmd;\n \n-\tif (!has_transparent_hugepage())\n+\tif (!pgtable_has_pmd_leaves())\n \t\treturn;\n \n \tpr_debug(\"Validating PMD based THP\\n\");\n@@ -997,7 +997,7 @@ static void __init destroy_args(struct pgtable_debug_args *args)\n \t}\n \n \tif (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026\n-\t    has_transparent_hugepage() \u0026\u0026\n+\t    pgtable_has_pmd_leaves() \u0026\u0026\n \t    args-\u003epmd_pfn != ULONG_MAX) {\n \t\tdebug_vm_pgtable_free_huge_page(args, args-\u003epmd_pfn, HPAGE_PMD_ORDER);\n \t\targs-\u003epmd_pfn = ULONG_MAX;\n@@ -1249,7 +1249,7 @@ static int __init init_args(struct pgtable_debug_args *args)\n \t}\n \n \tif (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026\n-\t    has_transparent_hugepage()) {\n+\t    pgtable_has_pmd_leaves()) {\n \t\tpage = debug_vm_pgtable_alloc_huge_page(args, HPAGE_PMD_ORDER);\n \t\tif (page) {\n \t\t\targs-\u003epmd_pfn = page_to_pfn(page);\ndiff --git a/mm/huge_memory.c b/mm/huge_memory.c\nindex 04e8a6b553435f..385a305e7af651 100644\n--- a/mm/huge_memory.c\n+++ b/mm/huge_memory.c\n@@ -129,6 +129,15 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\n \telse\n \t\tsupported_orders = THP_ORDERS_ALL_FILE_DEFAULT;\n \n+\tif (!pgtable_has_pmd_leaves()) {\n+\t\t/*\n+\t\t * If the CPU does not support PMD leaves, assume for\n+\t\t * now that it does not support PUD leaves and disable\n+\t\t * both folio orders.\n+\t\t */\n+\t\tsupported_orders \u0026= ~(BIT(PMD_ORDER) | BIT(PUD_ORDER));\n+\t}\n+\n \torders \u0026= supported_orders;\n \tif (!orders)\n \t\treturn 0;\n@@ -136,7 +145,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\n \tif (!vma-\u003evm_mm)\t\t/* vdso */\n \t\treturn 0;\n \n-\tif (thp_disabled_by_hw() || vma_thp_disabled(vma, vm_flags, forced_collapse))\n+\tif (vma_thp_disabled(vma, vm_flags, forced_collapse))\n \t\treturn 0;\n \n \t/* khugepaged doesn't collapse DAX vma, but page fault is fine. */\n@@ -874,7 +883,7 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)\n \t * disable all other sizes. powerpc's PMD_ORDER isn't a compile-time\n \t * constant so we have to do this here.\n \t */\n-\tif (!anon_orders_configured)\n+\tif (!anon_orders_configured \u0026\u0026 pgtable_has_pmd_leaves())\n \t\thuge_anon_orders_inherit = BIT(PMD_ORDER);\n \n \t*hugepage_kobj = kobject_create_and_add(\"transparent_hugepage\", mm_kobj);\n@@ -896,6 +905,15 @@ static int __init hugepage_init_sysfs(struct kobject **hugepage_kobj)\n \t}\n \n \torders = THP_ORDERS_ALL_ANON | THP_ORDERS_ALL_FILE_DEFAULT;\n+\tif (!pgtable_has_pmd_leaves()) {\n+\t\t/*\n+\t\t * If the CPU does not support PMD leaves, assume for\n+\t\t * now that it does not support PUD leaves and disable\n+\t\t * both folio orders.\n+\t\t */\n+\t\torders \u0026= ~(BIT(PMD_ORDER) | BIT(PUD_ORDER));\n+\t}\n+\n \torder = highest_order(orders);\n \twhile (orders) {\n \t\tthpsize = thpsize_create(order, *hugepage_kobj);\n@@ -1010,11 +1028,6 @@ static int __init hugepage_init(void)\n \tint err;\n \tstruct kobject *hugepage_kobj;\n \n-\tif (!has_transparent_hugepage()) {\n-\t\ttransparent_hugepage_flags = 1 \u003c\u003c TRANSPARENT_HUGEPAGE_UNSUPPORTED;\n-\t\treturn -EINVAL;\n-\t}\n-\n \t/*\n \t * hugepages can't be allocated by the buddy allocator\n \t */\ndiff --git a/mm/memory.c b/mm/memory.c\nindex 56b244552f1394..f39d9383494e69 100644\n--- a/mm/memory.c\n+++ b/mm/memory.c\n@@ -164,6 +164,15 @@ __setup(\"norandmaps\", disable_randmaps);\n \n unsigned long highest_memmap_pfn __read_mostly;\n \n+DEFINE_STATIC_KEY_TRUE(__arch_has_pmd_leaves_key);\n+EXPORT_SYMBOL(__arch_has_pmd_leaves_key);\n+\n+void __init pgtable_leaf_support_init(void)\n+{\n+\tif (!arch_has_pmd_leaves())\n+\t\tstatic_branch_disable(\u0026__arch_has_pmd_leaves_key);\n+}\n+\n void mm_trace_rss_stat(struct mm_struct *mm, int member)\n {\n \ttrace_rss_stat(mm, member);\n@@ -5567,7 +5576,7 @@ vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *pa\n \t * PMD mappings if THPs are disabled. As we already have a THP,\n \t * behave as if we are forcing a collapse.\n \t */\n-\tif (thp_disabled_by_hw() || vma_thp_disabled(vma, vma-\u003evm_flags,\n+\tif (!pgtable_has_pmd_leaves() || vma_thp_disabled(vma, vma-\u003evm_flags,\n \t\t\t\t\t\t     /* forced_collapse=*/ true))\n \t\treturn ret;\n \ndiff --git a/mm/mm_init.c b/mm/mm_init.c\nindex 711f821f7b3c72..dcc072db455872 100644\n--- a/mm/mm_init.c\n+++ b/mm/mm_init.c\n@@ -2699,6 +2699,7 @@ void __init mm_core_init(void)\n {\n \tarch_mm_preinit();\n \tinit_zero_page_pfn();\n+\tpgtable_leaf_support_init();\n \n \t/* Initializations relying on SMP setup */\n \tBUILD_BUG_ON(MAX_ZONELISTS \u003e 2);\ndiff --git a/mm/shmem.c b/mm/shmem.c\nindex 5071177059a964..008df558af237e 100644\n--- a/mm/shmem.c\n+++ b/mm/shmem.c\n@@ -689,7 +689,7 @@ static int shmem_parse_huge(const char *str)\n \telse\n \t\treturn -EINVAL;\n \n-\tif (!has_transparent_hugepage() \u0026\u0026\n+\tif (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026\n \t    huge != SHMEM_HUGE_NEVER \u0026\u0026 huge != SHMEM_HUGE_DENY)\n \t\treturn -EINVAL;\n \n@@ -1287,6 +1287,7 @@ static int shmem_getattr(struct mnt_idmap *idmap,\n {\n \tstruct inode *inode = path-\u003edentry-\u003ed_inode;\n \tstruct shmem_inode_info *info = SHMEM_I(inode);\n+\tunsigned int orders;\n \n \t/* Fast-path hint; recalc under info-\u003elock corrects any stale read. */\n \tif (data_race(info-\u003ealloced - info-\u003eswapped != inode-\u003ei_mapping-\u003enrpages))\n@@ -1303,8 +1304,11 @@ static int shmem_getattr(struct mnt_idmap *idmap,\n \t\t\tSTATX_ATTR_NODUMP);\n \tgeneric_fillattr(idmap, request_mask, inode, stat);\n \n-\tif (shmem_huge_global_enabled(inode, 0, 0, false, NULL, 0))\n-\t\tstat-\u003eblksize = HPAGE_PMD_SIZE;\n+\torders = shmem_huge_global_enabled(inode, 0, 0, false, NULL, 0);\n+\tif (!pgtable_has_pmd_leaves())\n+\t\torders \u0026= ~BIT(PMD_ORDER);\n+\tif (orders)\n+\t\tstat-\u003eblksize = PAGE_SIZE \u003c\u003c highest_order(orders);\n \n \tif (request_mask \u0026 STATX_BTIME) {\n \t\tstat-\u003eresult_mask |= STATX_BTIME;\n@@ -1826,16 +1830,19 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,\n \tunsigned long mask = READ_ONCE(huge_shmem_orders_always);\n \tunsigned long within_size_orders = READ_ONCE(huge_shmem_orders_within_size);\n \tvm_flags_t vm_flags = vma ? vma-\u003evm_flags : 0;\n-\tunsigned int global_orders;\n+\tunsigned int global_orders, disabled_orders = 0;\n \n-\tif (thp_disabled_by_hw() || (vma \u0026\u0026 vma_thp_disabled(vma, vm_flags, shmem_huge_force)))\n+\tif (vma \u0026\u0026 vma_thp_disabled(vma, vm_flags, shmem_huge_force))\n \t\treturn 0;\n \n+\tif (!pgtable_has_pmd_leaves())\n+\t\tdisabled_orders = BIT(PMD_ORDER);\n+\n \tglobal_orders = shmem_huge_global_enabled(inode, index, write_end,\n \t\t\t\t\t\t  shmem_huge_force, vma, vm_flags);\n \t/* Tmpfs huge pages allocation */\n \tif (!vma || !vma_is_anon_shmem(vma))\n-\t\treturn global_orders;\n+\t\treturn global_orders \u0026 ~disabled_orders;\n \n \t/*\n \t * Following the 'deny' semantics of the top level, force the huge\n@@ -1849,7 +1856,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,\n \t * means non-PMD sized THP can not override 'huge' mount option now.\n \t */\n \tif (shmem_huge == SHMEM_HUGE_FORCE)\n-\t\treturn READ_ONCE(huge_shmem_orders_inherit);\n+\t\treturn READ_ONCE(huge_shmem_orders_inherit) \u0026 ~disabled_orders;\n \n \t/* Allow mTHP that will be fully within i_size. */\n \tmask |= shmem_get_orders_within_size(inode, within_size_orders, index, 0);\n@@ -1860,6 +1867,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,\n \tif (global_orders \u003e 0)\n \t\tmask |= READ_ONCE(huge_shmem_orders_inherit);\n \n+\tmask \u0026= ~disabled_orders;\n \treturn THP_ORDERS_ALL_FILE_DEFAULT \u0026 mask;\n }\n \n@@ -4587,8 +4595,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)\n \tcase Opt_huge:\n \t\tctx-\u003ehuge = result.uint_32;\n \t\tif (ctx-\u003ehuge != SHMEM_HUGE_NEVER \u0026\u0026\n-\t\t    !(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026\n-\t\t      has_transparent_hugepage()))\n+\t\t    !IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))\n \t\t\tgoto unsupported_parameter;\n \t\tctx-\u003eseen |= SHMEM_SEEN_HUGE;\n \t\tbreak;\n@@ -5383,7 +5390,7 @@ void __init shmem_init(void)\n #endif\n \n #ifdef CONFIG_TRANSPARENT_HUGEPAGE\n-\tif (has_transparent_hugepage() \u0026\u0026 shmem_huge \u003e SHMEM_HUGE_DENY)\n+\tif (shmem_huge \u003e SHMEM_HUGE_DENY)\n \t\tSHMEM_SB(shm_mnt-\u003emnt_sb)-\u003ehuge = shmem_huge;\n \telse\n \t\tshmem_huge = SHMEM_HUGE_NEVER; /* just in case it was patched */\n@@ -5392,7 +5399,7 @@ void __init shmem_init(void)\n \t * Default to setting PMD-sized THP to inherit the global setting and\n \t * disable all other multi-size THPs.\n \t */\n-\tif (!shmem_orders_configured)\n+\tif (!shmem_orders_configured \u0026\u0026 pgtable_has_pmd_leaves())\n \t\thuge_shmem_orders_inherit = BIT(HPAGE_PMD_ORDER);\n #endif\n \treturn;\n"
}

2/1 2026/07/25 06:00 agent patch-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "TRANSPARENT_HUGEPAGE"
  ],
  "FocusSymbols": [
    "__thp_vma_allowable_orders",
    "shmem_allowable_huge_orders",
    "do_set_pmd"
  ],
  "Reasoning": "The patch modifies how THP support is checked and initialized, replacing `has_transparent_hugepage()` with `pgtable_has_pmd_leaves()`. It modifies core MM logic (THP, shmem, dax, nvdimm) to filter out PMD and PUD orders if the CPU does not support PMD leaves. This is functional and reachable.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit 8fd6564930b5838559c30d51d8a0a6ee87c25203
Author: syz-cluster <triage@syzkaller.com>
Date:   Sat Jul 25 06:00:13 2026 +0000

    syz-cluster: applied patch under review

diff --git a/Documentation/filesystems/tmpfs.rst b/Documentation/filesystems/tmpfs.rst
index d677e0428c3f68..46fc986c3388ac 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.
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index fa7b935f947ca0..2a0a7ddf8bee7e 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -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 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)
 #define pud_leaf(pud)	((pud_val(pud) & _PAGE_HUGE) != 0)
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 24fe85fa169d16..9339ebb0815f23 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -432,9 +432,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 #endif
 }
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-
-int has_transparent_hugepage(void)
+int arch_has_pmd_leaves(void)
 {
 	static unsigned int mask = -1;
 
@@ -450,9 +448,7 @@ int has_transparent_hugepage(void)
 	}
 	return mask == PM_HUGE_MASK;
 }
-EXPORT_SYMBOL(has_transparent_hugepage);
-
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE  */
+EXPORT_SYMBOL(arch_has_pmd_leaves);
 
 /*
  * Used for loading TLB entries before trap_init() has started, when we
diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index 8e5bd9902bed4e..d532e3f0dfc3b1 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -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__arch_has_pmd_leaves(void);
 #endif /* !__ASSEMBLER__ */
 
 #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h
index 7deb3a66890bcd..d523c80f44f717 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -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__arch_has_pmd_leaves(void);
 #endif	/* __ASSEMBLER__ */
 
 #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index f4db7d7fbd5c62..41166d44fa756e 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -1121,15 +1121,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())
@@ -1441,6 +1432,15 @@ static inline bool arch_needs_pgtable_deposit(void)
 
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+extern int hash__arch_has_pmd_leaves(void);
+static inline int arch_has_pmd_leaves(void)
+{
+	if (radix_enabled())
+		return radix__arch_has_pmd_leaves();
+	return hash__arch_has_pmd_leaves();
+}
+#define arch_has_pmd_leaves arch_has_pmd_leaves
+
 #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
 pte_t ptep_modify_prot_start(struct vm_area_struct *, unsigned long, pte_t *);
 void ptep_modify_prot_commit(struct vm_area_struct *, unsigned long,
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index da954e7797441f..e8b74528953fdc 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -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__arch_has_pmd_leaves(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;
diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c
index d9b5b751d7b75b..a67bc1723404c2 100644
--- a/arch/powerpc/mm/book3s64/hash_pgtable.c
+++ b/arch/powerpc/mm/book3s64/hash_pgtable.c
@@ -391,7 +391,9 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
 	return old_pmd;
 }
 
-int hash__has_transparent_hugepage(void)
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+int hash__arch_has_pmd_leaves(void)
 {
 
 	if (!mmu_has_feature(MMU_FTR_16M_PAGE))
@@ -420,9 +422,7 @@ int hash__has_transparent_hugepage(void)
 
 	return 1;
 }
-EXPORT_SYMBOL_GPL(hash__has_transparent_hugepage);
-
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+EXPORT_SYMBOL_GPL(hash__arch_has_pmd_leaves);
 
 #ifdef CONFIG_STRICT_KERNEL_RWX
 
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index e882663a58e776..24ee90c7e9bf6b 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -1825,13 +1825,13 @@ static inline int pmd_trans_huge(pmd_t pmd)
 {
 	return pmd_leaf(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;
 }
-#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)
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 8e0018fadd14e6..3c6a641e6c211d 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -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 arch_has_pmd_leaves arch_has_pmd_leaves
+static inline int arch_has_pmd_leaves(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);
diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h
index 81e4af49e39c10..35744ff6592ac9 100644
--- a/drivers/dax/dax-private.h
+++ b/drivers/dax/dax-private.h
@@ -123,7 +123,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;
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index 8fa9c16aba7ea0..457eb54e7ab6fc 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -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;
 }
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index c745f7ad22987f..525acea2eb59cb 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,
@@ -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,
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 8c093c119e5a82..d571d161a84b3c 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -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>
 
@@ -2313,6 +2314,21 @@ static inline const char *pgtable_level_to_str(enum pgtable_level level)
 	}
 }
 
+#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)
@@ -2328,8 +2344,8 @@ static inline const char *pgtable_level_to_str(enum pgtable_level level)
 #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_HAVE_ARCH_TRANSPARENT_HUGEPAGE)
 #endif
 
 #ifndef has_transparent_pud_hugepage
diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c
index 2875fd22d7bb02..25038b74c7bc67 100644
--- a/mm/debug_vm_pgtable.c
+++ b/mm/debug_vm_pgtable.c
@@ -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);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 04e8a6b553435f..385a305e7af651 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -129,6 +129,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;
@@ -136,7 +145,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 (vma_thp_disabled(vma, vm_flags, forced_collapse))
 		return 0;
 
 	/* khugepaged doesn't collapse DAX vma, but page fault is fine. */
@@ -874,7 +883,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);
@@ -896,6 +905,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);
@@ -1010,11 +1028,6 @@ static int __init hugepage_init(void)
 	int err;
 	struct kobject *hugepage_kobj;
 
-	if (!has_transparent_hugepage()) {
-		transparent_hugepage_flags = 1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED;
-		return -EINVAL;
-	}
-
 	/*
 	 * hugepages can't be allocated by the buddy allocator
 	 */
diff --git a/mm/memory.c b/mm/memory.c
index 56b244552f1394..f39d9383494e69 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -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 (!arch_has_pmd_leaves())
+		static_branch_disable(&__arch_has_pmd_leaves_key);
+}
+
 void mm_trace_rss_stat(struct mm_struct *mm, int member)
 {
 	trace_rss_stat(mm, member);
@@ -5567,7 +5576,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/mm_init.c b/mm/mm_init.c
index 711f821f7b3c72..dcc072db455872 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -2699,6 +2699,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);
diff --git a/mm/shmem.c b/mm/shmem.c
index 5071177059a964..008df558af237e 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -689,7 +689,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;
 
@@ -1287,6 +1287,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))
@@ -1303,8 +1304,11 @@ 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 (!pgtable_has_pmd_leaves())
+		orders &= ~BIT(PMD_ORDER);
+	if (orders)
+		stat->blksize = PAGE_SIZE << highest_order(orders);
 
 	if (request_mask & STATX_BTIME) {
 		stat->result_mask |= STATX_BTIME;
@@ -1826,16 +1830,19 @@ 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 (thp_disabled_by_hw() || (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);
 	/* Tmpfs huge pages allocation */
 	if (!vma || !vma_is_anon_shmem(vma))
-		return global_orders;
+		return global_orders & ~disabled_orders;
 
 	/*
 	 * Following the 'deny' semantics of the top level, force the huge
@@ -1849,7 +1856,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);
@@ -1860,6 +1867,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;
 }
 
@@ -4587,8 +4595,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;
@@ -5383,7 +5390,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 */
@@ -5392,7 +5399,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;

3/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 11639
							output: 25
							thoughts: 699
						

Thoughts:
**Analyzing the THP Support Patch**

Okay, so I'm looking at this patch and it's making some pretty significant changes to how we handle Transparent Huge Pages (THP) support. It looks like the core of the change is renaming `has_transparent_hugepage()` to either `arch_has_pmd_leaves()` or `pgtable_has_pmd_leaves()`. This isn't just a name change; it's also impacting how we disable THP when the underlying hardware doesn't support it, introducing a static key called `__arch_has_pmd_leaves_key`.

This ripples through quite a few critical areas: `shmem.c`, `huge_memory.c`, `memory.c`, `mm_init.c`, `debug_vm_pgtable.c`, `pfn_devs.c`, `dax-private.h`, and, of course, the architecture-specific code for mips, powerpc, s390, and x86. The fact that it touches `shmem`, `dax`, and `nvdimm` is a big deal; those are all intimately linked to memory management and performance.

So, the key thing here is that `pgtable_has_pmd_leaves()` is now the gatekeeper for THP support, and it's being used to filter certain order sizes, as seen in modifications to `shmem_allowable_huge_orders` and `__thp_vma_allowable_orders`. Essentially, if `!pgtable_has_pmd_leaves()`, certain memory order sizes are excluded.

Looking at the code snippet, it's clear this is a static key implementation, which is how we’re deciding at runtime whether to enable it. I see the `DECLARE_STATIC_KEY_TRUE` and the logic that seems to disable the key if the architecture doesn't have PMD leaves in `pgtable_leaf_support_init()`. This looks functional and the code is definitely reachable in QEMU/GCE, so I can test it.

Alright, time to prioritize some fuzzing targets. Based on the scope of the change, functions like `shmem_allowable_huge_orders`, `__thp_vma_allowable_orders`, `shmem_getattr`, `shmem_parse_one`, `shmem_parse_huge`, and `do_set_pmd` are going to be critical. Now, `shmem_allowable_huge_orders` is definitely reachable; I know it's invoked during shmem page faults and allocation. And `__thp_vma_allowable_orders` is used during THP allocation. Let's see how `__thp_vma_allowable_orders` is defined. Good. Now, let’s dig a bit deeper and use `default_api:grepper` to understand how this is used and where it’s defined.



4/2 2026/07/25 06:00 tool grepper
0m Args:
{
  "Expression": "__thp_vma_allowable_orders"
}

Results:
{
  "Output": "include/linux/huge_mm.h=275=static inline unsigned long thp_vma_suitable_orders(struct vm_area_struct *vma,\n--\ninclude/linux/huge_mm.h-297-\ninclude/linux/huge_mm.h:298:unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\ninclude/linux/huge_mm.h-299-\t\t\t\t\t vm_flags_t vm_flags,\n--\ninclude/linux/huge_mm.h=319=unsigned long thp_vma_allowable_orders(struct vm_area_struct *vma,\n--\ninclude/linux/huge_mm.h-341-\ninclude/linux/huge_mm.h:342:\treturn __thp_vma_allowable_orders(vma, vm_flags, type, orders);\ninclude/linux/huge_mm.h-343-}\n--\nmm/huge_memory.c=107=static bool vma_is_special_huge(const struct vm_area_struct *vma)\n--\nmm/huge_memory.c-113-\nmm/huge_memory.c:114:unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\nmm/huge_memory.c-115-\t\t\t\t\t vm_flags_t vm_flags,\n"
}

5/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 13357
							output: 23
							thoughts: 15
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience, and delivered as if they were my own:

**Analyzing `shmem_allowable_huge_orders`**

Alright, let's dive into this `shmem_allowable_huge_orders` variable. It's a critical knob when tuning shared memory behavior, especially on systems with NUMA architectures or those needing to squeeze every last bit of performance out of large memory allocations. My initial thought is to ensure I fully understand its current setting. I need to establish what's permissible, given the underlying hardware and the intended application profile.

I'm thinking, "Is this configured appropriately for the workload?" Are we under-utilizing potential huge page allocations, or perhaps being overly aggressive and risking fragmentation or other adverse side effects? Depending on what I'm looking at, maybe I need to check the OS kernel parameters, and the application's memory allocation patterns, to make a decision about my next steps.

I should also consider whether the current settings are leading to any unexpected behavior. Are we seeing significant page faults, increased memory latencies, or any other signs that the memory subsystem isn't performing optimally? Based on this diagnostic, I have to ensure the settings are adjusted to allow for maximum efficiency, which is important to me.



6/2 2026/07/25 06:00 tool grepper
0m Args:
{
  "Expression": "shmem_allowable_huge_orders"
}

Results:
{
  "Output": "include/linux/shmem_fs.h=126=int shmem_unuse(unsigned int type);\n--\ninclude/linux/shmem_fs.h-128-#if defined(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026 defined(CONFIG_SHMEM)\ninclude/linux/shmem_fs.h:129:unsigned long shmem_allowable_huge_orders(struct inode *inode,\ninclude/linux/shmem_fs.h-130-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\ninclude/linux/shmem_fs.h=132=bool shmem_hpage_pmd_enabled(void);\ninclude/linux/shmem_fs.h-133-#else\ninclude/linux/shmem_fs.h:134:static inline unsigned long shmem_allowable_huge_orders(struct inode *inode,\ninclude/linux/shmem_fs.h-135-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\nmm/huge_memory.c=114=unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\n--\nmm/huge_memory.c-190-\tif (!in_pf \u0026\u0026 shmem_file(vma-\u003evm_file))\nmm/huge_memory.c:191:\t\treturn orders \u0026 shmem_allowable_huge_orders(file_inode(vma-\u003evm_file),\nmm/huge_memory.c-192-\t\t\t\t\t\t   vma, vma_start_pgoff(vma), 0,\n--\nmm/shmem.c=1809=bool shmem_hpage_pmd_enabled(void)\n--\nmm/shmem.c-1825-\nmm/shmem.c:1826:unsigned long shmem_allowable_huge_orders(struct inode *inode,\nmm/shmem.c-1827-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\nmm/shmem.c=2422=static int shmem_get_folio_gfp(struct inode *inode, pgoff_t index,\n--\nmm/shmem.c-2503-\t/* Find hugepage orders that are allowed for anonymous shmem and tmpfs. */\nmm/shmem.c:2504:\torders = shmem_allowable_huge_orders(inode, vma, index, write_end, false);\nmm/shmem.c-2505-\tif (orders \u003e 0) {\n"
}

7/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 14316
							output: 18
							thoughts: 10
						

Thoughts:
Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to an expert:

**Investigating `shmem_getattr`**

Alright, let's take a look at `shmem_getattr`. It's a key function, so let's get right into it, what's its implementation looking like? I need to check the function's definition, potential pitfalls, and how it handles various error conditions. I'm going to want to verify how it interacts with the underlying shared memory management. Are there any race conditions, memory leaks, or concurrency issues I need to be concerned about? Perhaps there are aspects that need further clarification, and I will want to read the documentation. I can cross-reference the function implementation with the rest of the shmem codebase. I should also check and review the surrounding code that calls this function.



8/2 2026/07/25 06:00 tool grepper
0m Args:
{
  "Expression": "shmem_getattr"
}

Results:
{
  "Output": "mm/shmem.c=1282=EXPORT_SYMBOL_GPL(shmem_truncate_range);\nmm/shmem.c-1283-\nmm/shmem.c:1284:static int shmem_getattr(struct mnt_idmap *idmap,\nmm/shmem.c-1285-\t\t\t const struct path *path, struct kstat *stat,\n--\nmm/shmem.c=4329=static const struct inode_operations shmem_short_symlink_operations = {\nmm/shmem.c:4330:\t.getattr\t= shmem_getattr,\nmm/shmem.c-4331-\t.setattr\t= shmem_setattr,\n--\nmm/shmem.c=4338=static const struct inode_operations shmem_symlink_inode_operations = {\nmm/shmem.c:4339:\t.getattr\t= shmem_getattr,\nmm/shmem.c-4340-\t.setattr\t= shmem_setattr,\n--\nmm/shmem.c=5174=static const struct inode_operations shmem_inode_operations = {\nmm/shmem.c:5175:\t.getattr\t= shmem_getattr,\nmm/shmem.c-5176-\t.setattr\t= shmem_setattr,\n--\nmm/shmem.c=5185=static const struct inode_operations shmem_dir_inode_operations = {\nmm/shmem.c-5186-#ifdef CONFIG_TMPFS\nmm/shmem.c:5187:\t.getattr\t= shmem_getattr,\nmm/shmem.c-5188-\t.create\t\t= shmem_create,\n--\nmm/shmem.c=5211=static const struct inode_operations shmem_special_inode_operations = {\nmm/shmem.c:5212:\t.getattr\t= shmem_getattr,\nmm/shmem.c-5213-#ifdef CONFIG_TMPFS_XATTR\n"
}

9/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 15042
							output: 20
							thoughts: 12
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience, and delivered as a first-person summary:

**Deconstructing `do_set_pmd`**

Alright, time to dive in. My mind immediately went to the function `do_set_pmd`. Now, I need to really get a handle on what's happening. The name itself suggests a "set" operation, a fundamental part of memory management, but I need to quickly refresh my understanding of *precisely* what the "PMD" represents in this context – a Page Middle Directory entry, right? Is this about setting a new mapping, updating existing metadata, or dealing with some form of memory allocation or invalidation? I have to consider the nuances of the architecture, of course. Is there any obvious place to start digging deeper and find what it’s called with? What kind of arguments are we passing, and what's the expected behavior? I need to check the function's declaration, implementation, and any related comments to quickly get my bearings and anticipate any potential trouble spots or performance bottlenecks. I also have to keep an eye out for potential synchronization primitives or concurrency issues within this function. It's a key piece of the puzzle, and I want a clear picture.



10/2 2026/07/25 06:00 tool grepper
0m Args:
{
  "Expression": "do_set_pmd"
}

Results:
{
  "Output": "include/linux/mm.h=2031=static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)\n--\ninclude/linux/mm.h-2037-\ninclude/linux/mm.h:2038:vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *page);\ninclude/linux/mm.h-2039-void set_pte_range(struct vm_fault *vmf, struct folio *folio,\n--\nmm/filemap.c=3710=static bool filemap_map_pmd(struct vm_fault *vmf, struct folio *folio,\n--\nmm/filemap.c-3723-\t\tstruct page *page = folio_file_page(folio, start);\nmm/filemap.c:3724:\t\tvm_fault_t ret = do_set_pmd(vmf, folio, page);\nmm/filemap.c-3725-\t\tif (!ret) {\n--\nmm/khugepaged.c=1819=static enum scan_result set_huge_pmd(struct vm_area_struct *vma, unsigned long addr,\n--\nmm/khugepaged.c-1847-\tvmf.pmd = pmdp;\nmm/khugepaged.c:1848:\tif (do_set_pmd(\u0026vmf, folio, page))\nmm/khugepaged.c-1849-\t\treturn SCAN_FAIL;\n--\nmm/memory.c=5551=static void deposit_prealloc_pte(struct vm_fault *vmf)\n--\nmm/memory.c-5563-\nmm/memory.c:5564:vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *page)\nmm/memory.c-5565-{\n--\nmm/memory.c-5639-#else\nmm/memory.c:5640:vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *page)\nmm/memory.c-5641-{\n--\nmm/memory.c=5713=vm_fault_t finish_fault(struct vm_fault *vmf)\n--\nmm/memory.c-5763-\t\tif (!needs_fallback \u0026\u0026 folio_test_pmd_mappable(folio)) {\nmm/memory.c:5764:\t\t\tret = do_set_pmd(vmf, folio, page);\nmm/memory.c-5765-\t\t\tif (ret != VM_FAULT_FALLBACK)\n"
}

11/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 16018
							output: 35
							thoughts: 203
						

Thoughts:
**Analyzing the THP Patch**

Okay, so this patch is making some interesting changes related to Transparent Huge Pages (THP). I see it's touching `do_set_pmd`, replacing the `thp_disabled_by_hw()` check with `!pgtable_has_pmd_leaves()`. That's a key shift in how it's determining whether or not to allow PMD-level THP. Interesting.

Then, it goes on to modify `shmem_allowable_huge_orders`, `__thp_vma_allowable_orders`, and `shmem_getattr` to also incorporate this `!pgtable_has_pmd_leaves()` check, effectively filtering out PMD orders under the same condition. It looks like it's trying to harmonize this check across the board for all the functions that deal with the huge page orders.

Hold on... I've got a wrinkle. `__thp_vma_allowable_orders` is typically an inline function, isn't it? It's defined in `include/linux/huge_mm.h`. Why is it showing up in `mm/huge_memory.c` in the patch? I'll need to double check the context. Let's go to `mm/huge_memory.c` and see what the patch is doing to that function. I need to understand this discrepancy to fully grasp what's going on here. This could be important.



12/2 2026/07/25 06:00 tool read-file
0m Args:
{
  "File": "mm/huge_memory.c",
  "FirstLine": 120,
  "LineCount": 50
}

Results:
{
  "Contents": " 120:\t\tconst bool in_pf = type == TVA_PAGEFAULT;\n 121:\t\tconst bool forced_collapse = type == TVA_FORCED_COLLAPSE;\n 122:\t\tunsigned long supported_orders;\n 123:\t\n 124:\t\t/* Check the intersection of requested and supported orders. */\n 125:\t\tif (vma_is_anonymous(vma))\n 126:\t\t\tsupported_orders = THP_ORDERS_ALL_ANON;\n 127:\t\telse if (vma_is_dax(vma) || vma_is_special_huge(vma))\n 128:\t\t\tsupported_orders = THP_ORDERS_ALL_SPECIAL_DAX;\n 129:\t\telse\n 130:\t\t\tsupported_orders = THP_ORDERS_ALL_FILE_DEFAULT;\n 131:\t\n 132:\t\tif (!pgtable_has_pmd_leaves()) {\n 133:\t\t\t/*\n 134:\t\t\t * If the CPU does not support PMD leaves, assume for\n 135:\t\t\t * now that it does not support PUD leaves and disable\n 136:\t\t\t * both folio orders.\n 137:\t\t\t */\n 138:\t\t\tsupported_orders \u0026= ~(BIT(PMD_ORDER) | BIT(PUD_ORDER));\n 139:\t\t}\n 140:\t\n 141:\t\torders \u0026= supported_orders;\n 142:\t\tif (!orders)\n 143:\t\t\treturn 0;\n 144:\t\n 145:\t\tif (!vma-\u003evm_mm)\t\t/* vdso */\n 146:\t\t\treturn 0;\n 147:\t\n 148:\t\tif (vma_thp_disabled(vma, vm_flags, forced_collapse))\n 149:\t\t\treturn 0;\n 150:\t\n 151:\t\t/* khugepaged doesn't collapse DAX vma, but page fault is fine. */\n 152:\t\tif (vma_is_dax(vma))\n 153:\t\t\treturn in_pf ? orders : 0;\n 154:\t\n 155:\t\t/*\n 156:\t\t * khugepaged special VMA and hugetlb VMA.\n 157:\t\t * Must be checked after dax since some dax mappings may have\n 158:\t\t * VM_MIXEDMAP set.\n 159:\t\t */\n 160:\t\tif (!in_pf \u0026\u0026 !smaps \u0026\u0026 (vm_flags \u0026 VM_NO_KHUGEPAGED))\n 161:\t\t\treturn 0;\n 162:\t\n 163:\t\t/*\n 164:\t\t * Check alignment for file vma and size for both file and anon vma by\n 165:\t\t * filtering out the unsuitable orders.\n 166:\t\t *\n 167:\t\t * Skip the check for page fault. Huge fault does the check in fault\n 168:\t\t * handlers.\n 169:\t\t */\n"
}

13/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 17347
							output: 23
							thoughts: 226
						

Thoughts:
**Analyzing Shmem and THP Functionality**

Okay, this looks achievable. My first thought is to zero in on the key symbols involved. I see a few potential candidates: `__thp_vma_allowable_orders`, `shmem_allowable_huge_orders`, `shmem_getattr`, `shmem_parse_one`, `shmem_parse_huge`, and `do_set_pmd`.

Wait, a quick scan reveals that `__thp_vma_allowable_orders` and `shmem_allowable_huge_orders` are *not* declared static - that's something to keep in mind. Now, `shmem_getattr` is static, which is good, but it's an inode operation, so it's probably fine to use that one. Both `shmem_parse_one` and `shmem_parse_huge` are also static. And finally, `do_set_pmd` is *not* static, so I'll need to remember that.

Right, now that I have those in mind, I need to check if `TRANSPARENT_HUGEPAGE` is required for my specific needs. Ah, yes, it's definitely required. So, let's now jump into `mm/shmem.c` and take a closer look at `shmem_allowable_huge_orders` and make sure it behaves as expected.



14/2 2026/07/25 06:00 tool grepper
0m Args:
{
  "Expression": "shmem_allowable_huge_orders"
}

Results:
{
  "Output": "include/linux/shmem_fs.h=126=int shmem_unuse(unsigned int type);\n--\ninclude/linux/shmem_fs.h-128-#if defined(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026 defined(CONFIG_SHMEM)\ninclude/linux/shmem_fs.h:129:unsigned long shmem_allowable_huge_orders(struct inode *inode,\ninclude/linux/shmem_fs.h-130-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\ninclude/linux/shmem_fs.h=132=bool shmem_hpage_pmd_enabled(void);\ninclude/linux/shmem_fs.h-133-#else\ninclude/linux/shmem_fs.h:134:static inline unsigned long shmem_allowable_huge_orders(struct inode *inode,\ninclude/linux/shmem_fs.h-135-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\nmm/huge_memory.c=114=unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\n--\nmm/huge_memory.c-190-\tif (!in_pf \u0026\u0026 shmem_file(vma-\u003evm_file))\nmm/huge_memory.c:191:\t\treturn orders \u0026 shmem_allowable_huge_orders(file_inode(vma-\u003evm_file),\nmm/huge_memory.c-192-\t\t\t\t\t\t   vma, vma_start_pgoff(vma), 0,\n--\nmm/shmem.c=1809=bool shmem_hpage_pmd_enabled(void)\n--\nmm/shmem.c-1825-\nmm/shmem.c:1826:unsigned long shmem_allowable_huge_orders(struct inode *inode,\nmm/shmem.c-1827-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\nmm/shmem.c=2422=static int shmem_get_folio_gfp(struct inode *inode, pgoff_t index,\n--\nmm/shmem.c-2503-\t/* Find hugepage orders that are allowed for anonymous shmem and tmpfs. */\nmm/shmem.c:2504:\torders = shmem_allowable_huge_orders(inode, vma, index, write_end, false);\nmm/shmem.c-2505-\tif (orders \u003e 0) {\n"
}

15/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 18550
							output: 20
							thoughts: 38
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating Memory Management Options**

Alright, the need for `TRANSPARENT_HUGEPAGE` is clear. Now I need to understand its interplay with the overall memory management strategy, particularly as it relates to shared memory. Let me see... I should double-check the configuration for `CONFIG_SHMEM`. I need to ensure that the shared memory subsystem is properly configured and isn't somehow clashing with or preventing transparent hugepages from operating as expected. I need to understand if there is an interaction with shared memory configuration that is relevant.

Next, I should quickly review the implementation details of `do_set_pmd`. I'll need to confirm how the PMD is being updated, especially in the context of hugepages. I need to verify what specific operations are taking place at the Page Table level, as this function holds critical information for understanding if there is a conflict. Are we mapping huge pages directly, or are we falling back to smaller page sizes in certain scenarios? Understanding that function will illuminate how page table entries are set, which is absolutely vital when dealing with hugepages, to see how the overall system interacts.



16/2 2026/07/25 06:00 tool grepper
0m Args:
{
  "Expression": "do_set_pmd"
}

Results:
{
  "Output": "include/linux/mm.h=2031=static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)\n--\ninclude/linux/mm.h-2037-\ninclude/linux/mm.h:2038:vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *page);\ninclude/linux/mm.h-2039-void set_pte_range(struct vm_fault *vmf, struct folio *folio,\n--\nmm/filemap.c=3710=static bool filemap_map_pmd(struct vm_fault *vmf, struct folio *folio,\n--\nmm/filemap.c-3723-\t\tstruct page *page = folio_file_page(folio, start);\nmm/filemap.c:3724:\t\tvm_fault_t ret = do_set_pmd(vmf, folio, page);\nmm/filemap.c-3725-\t\tif (!ret) {\n--\nmm/khugepaged.c=1819=static enum scan_result set_huge_pmd(struct vm_area_struct *vma, unsigned long addr,\n--\nmm/khugepaged.c-1847-\tvmf.pmd = pmdp;\nmm/khugepaged.c:1848:\tif (do_set_pmd(\u0026vmf, folio, page))\nmm/khugepaged.c-1849-\t\treturn SCAN_FAIL;\n--\nmm/memory.c=5551=static void deposit_prealloc_pte(struct vm_fault *vmf)\n--\nmm/memory.c-5563-\nmm/memory.c:5564:vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *page)\nmm/memory.c-5565-{\n--\nmm/memory.c-5639-#else\nmm/memory.c:5640:vm_fault_t do_set_pmd(struct vm_fault *vmf, struct folio *folio, struct page *page)\nmm/memory.c-5641-{\n--\nmm/memory.c=5713=vm_fault_t finish_fault(struct vm_fault *vmf)\n--\nmm/memory.c-5763-\t\tif (!needs_fallback \u0026\u0026 folio_test_pmd_mappable(folio)) {\nmm/memory.c:5764:\t\t\tret = do_set_pmd(vmf, folio, page);\nmm/memory.c-5765-\t\t\tif (ret != VM_FAULT_FALLBACK)\n"
}

17/2 2026/07/25 06:00 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 19543
							output: 22
							thoughts: 32
						

Thoughts:
Here's my summary, as though I'm thinking through this process:

**Diving into Page Table Initialization**

Okay, so I'm digging into how the page tables are set up. I remember seeing `do_set_pmd` somewhere in the `mm` subsystem... right, it's in `mm/memory.c`. Now, where does this whole process actually *start*? I need to trace this back. Let's see... I'm pretty sure I need to focus on how the leaf node support is initialized to understand this. That means checking `pgtable_leaf_support_init` next. I wonder what that function sets up, and what aspects of the PMD it's setting the ground rules for... Let's see what's in there.



18/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "pgtable_leaf_support_init"
}

Results:
{
  "Output": "include/linux/pgtable.h=2319=static inline bool pgtable_has_pmd_leaves(void)\n--\ninclude/linux/pgtable.h-2322-}\ninclude/linux/pgtable.h:2323:void __init pgtable_leaf_support_init(void);\ninclude/linux/pgtable.h-2324-#else\ninclude/linux/pgtable.h=2325=static inline bool pgtable_has_pmd_leaves(void)\n--\ninclude/linux/pgtable.h-2328-}\ninclude/linux/pgtable.h:2329:static inline void __init pgtable_leaf_support_init(void) { }\ninclude/linux/pgtable.h-2330-#endif\n--\nmm/memory.c=168=EXPORT_SYMBOL(__arch_has_pmd_leaves_key);\nmm/memory.c-169-\nmm/memory.c:170:void __init pgtable_leaf_support_init(void)\nmm/memory.c-171-{\n--\nmm/mm_init.c=2698=void __init mm_core_init(void)\n--\nmm/mm_init.c-2701-\tinit_zero_page_pfn();\nmm/mm_init.c:2702:\tpgtable_leaf_support_init();\nmm/mm_init.c-2703-\n"
}

19/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 20132
							output: 25
							thoughts: 105
						

Thoughts:
**Analyzing the Proposed Patch**

Okay, so I'm looking at this patch and it seems to be touching several key areas. I see it's modifying `shmem_allowable_huge_orders`, `__thp_vma_allowable_orders`, `do_set_pmd`, and `shmem_getattr`. Those are all relevant symbols; I'm happy to see those specific functions targeted, they indicate a clear focus. Wait a second, though... I'm noticing that `__thp_vma_allowable_orders` is not static. That means it's exported or global, and can be accessed from other parts of the kernel. I should confirm that that's the case. To make sure I understand the scope of the change, let's take a look at the definition of `__thp_vma_allowable_orders` in `mm/huge_memory.c`. I need to understand how widely this variable is being used.



20/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "__thp_vma_allowable_orders"
}

Results:
{
  "Output": "include/linux/huge_mm.h=275=static inline unsigned long thp_vma_suitable_orders(struct vm_area_struct *vma,\n--\ninclude/linux/huge_mm.h-297-\ninclude/linux/huge_mm.h:298:unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\ninclude/linux/huge_mm.h-299-\t\t\t\t\t vm_flags_t vm_flags,\n--\ninclude/linux/huge_mm.h=319=unsigned long thp_vma_allowable_orders(struct vm_area_struct *vma,\n--\ninclude/linux/huge_mm.h-341-\ninclude/linux/huge_mm.h:342:\treturn __thp_vma_allowable_orders(vma, vm_flags, type, orders);\ninclude/linux/huge_mm.h-343-}\n--\nmm/huge_memory.c=107=static bool vma_is_special_huge(const struct vm_area_struct *vma)\n--\nmm/huge_memory.c-113-\nmm/huge_memory.c:114:unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,\nmm/huge_memory.c-115-\t\t\t\t\t vm_flags_t vm_flags,\n"
}

21/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 20828
							output: 20
							thoughts: 78
						

Thoughts:
Here's my take on the situation:

**Analyzing Memory Management in the Shared Memory (SHMEM) System**

Alright, let's break this down. My initial observation is that `__thp_vma_allowable_orders`, `shmem_allowable_huge_orders`, and `do_set_pmd` are all globally accessible functions. I recognize their significance, these are the core building blocks for memory management within the kernel. It seems like the architecture is using a mix of global and localized function calls for memory control, which makes for a more complex picture. And then, there's `shmem_getattr`, a static function, but used as a callback. That's a classic pattern to watch out for – how is the callback interacting with the static context and what's the lifecycle of that static scope? This means the overall memory management scheme is likely a distributed mix of callbacks and direct calls. Let's delve into `shmem_parse_one`. This function is likely where all of these functions come together. I want to see how the system is actually parsing memory configuration and how these global and static functions interact at a fundamental level.



22/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "shmem_parse_one"
}

Results:
{
  "Output": "mm/shmem.c=4521=static int shmem_parse_opt_casefold(struct fs_context *fc, struct fs_parameter *param,\n--\nmm/shmem.c-4527-\nmm/shmem.c:4528:static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)\nmm/shmem.c-4529-{\n--\nmm/shmem.c=5085=static const struct fs_context_operations shmem_fs_context_ops = {\n--\nmm/shmem.c-5089-\t.parse_monolithic\t= shmem_parse_monolithic,\nmm/shmem.c:5090:\t.parse_param\t\t= shmem_parse_one,\nmm/shmem.c-5091-\t.reconfigure\t\t= shmem_reconfigure,\n"
}

23/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 21402
							output: 22
							thoughts: 98
						

Thoughts:
**Analyzing Huge Page Configuration in Shared Memory**

Okay, so I'm looking at how huge pages are handled, specifically within shared memory. The code has a static function, `shmem_parse_one`, that's relevant. I need to understand the configuration interplay here. I should probably focus on `shmem_allowable_huge_orders`, and also `__thp_vma_allowable_orders` and `do_set_pmd` which seem like key pieces of the puzzle. I wonder, are there *other* configuration options I'm missing that influence this behavior?

Right, need to make sure I'm not overlooking anything. The obvious one, of course, is `CONFIG_TRANSPARENT_HUGEPAGE`, which is central to the concept.  And I'd also expect `CONFIG_SHMEM` to be enabled, as shared memory is usually a standard feature. Let me start by double-checking the status of `CONFIG_TRANSPARENT_HUGEPAGE` – that's the place to start, it's core to the enabling of all of this.



24/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "config TRANSPARENT_HUGEPAGE"
}

Results:
{
  "Output": "mm/Kconfig=829=config MM_ID\n--\nmm/Kconfig-831-\nmm/Kconfig:832:menuconfig TRANSPARENT_HUGEPAGE\nmm/Kconfig-833-\tbool \"Transparent Hugepage Support\"\n--\nmm/Kconfig=850=choice\n--\nmm/Kconfig-855-\nmm/Kconfig:856:\tconfig TRANSPARENT_HUGEPAGE_ALWAYS\nmm/Kconfig-857-\t\tbool \"always\"\n--\nmm/Kconfig-862-\nmm/Kconfig:863:\tconfig TRANSPARENT_HUGEPAGE_MADVISE\nmm/Kconfig-864-\t\tbool \"madvise\"\n--\nmm/Kconfig-871-\nmm/Kconfig:872:\tconfig TRANSPARENT_HUGEPAGE_NEVER\nmm/Kconfig-873-\t\tbool \"never\"\n--\nmm/Kconfig=879=choice\n--\nmm/Kconfig-888-\nmm/Kconfig:889:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_NEVER\nmm/Kconfig-890-\t\tbool \"never\"\n--\nmm/Kconfig-898-\nmm/Kconfig:899:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ALWAYS\nmm/Kconfig-900-\t\tbool \"always\"\n--\nmm/Kconfig-906-\nmm/Kconfig:907:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_WITHIN_SIZE\nmm/Kconfig-908-\t\tbool \"within_size\"\n--\nmm/Kconfig-914-\nmm/Kconfig:915:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ADVISE\nmm/Kconfig-916-\t\tbool \"advise\"\n--\nmm/Kconfig=924=choice\n--\nmm/Kconfig-933-\nmm/Kconfig:934:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_NEVER\nmm/Kconfig-935-\t\tbool \"never\"\n--\nmm/Kconfig-942-\nmm/Kconfig:943:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ALWAYS\nmm/Kconfig-944-\t\tbool \"always\"\n--\nmm/Kconfig-950-\nmm/Kconfig:951:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_WITHIN_SIZE\nmm/Kconfig-952-\t\tbool \"within_size\"\n--\nmm/Kconfig-958-\nmm/Kconfig:959:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ADVISE\nmm/Kconfig-960-\t\tbool \"advise\"\n"
}

25/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 22472
							output: 25
							thoughts: 174
						

Thoughts:
**Investigating shmem_allowable_huge_orders and TRANSPARENT_HUGEPAGE**

Okay, so we're looking at `TRANSPARENT_HUGEPAGE`. That's the config in play. Now, I need to double-check `shmem_allowable_huge_orders`. Let's refresh our memory on that; it's tucked away in `mm/shmem.c`. The signature I expect to see is:

```c
unsigned long shmem_allowable_huge_orders(struct inode *inode,
				struct vm_area_struct *vma, pgoff_t index,
				bool shmem_huge_force)
```

Hang on a second... Going back through the patches, I see something different. There's an extra parameter, `loff_t write_end`. The patched version reads:

```c
unsigned long shmem_allowable_huge_orders(struct inode *inode,
				struct vm_area_struct *vma, pgoff_t index,
				loff_t write_end, bool shmem_huge_force)
```

Time to consult the source tree and verify the current signature. I need to be absolutely certain of the function prototype we're working with here.



26/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "unsigned long shmem_allowable_huge_orders"
}

Results:
{
  "Output": "include/linux/shmem_fs.h=126=int shmem_unuse(unsigned int type);\n--\ninclude/linux/shmem_fs.h-128-#if defined(CONFIG_TRANSPARENT_HUGEPAGE) \u0026\u0026 defined(CONFIG_SHMEM)\ninclude/linux/shmem_fs.h:129:unsigned long shmem_allowable_huge_orders(struct inode *inode,\ninclude/linux/shmem_fs.h-130-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\ninclude/linux/shmem_fs.h=132=bool shmem_hpage_pmd_enabled(void);\ninclude/linux/shmem_fs.h-133-#else\ninclude/linux/shmem_fs.h:134:static inline unsigned long shmem_allowable_huge_orders(struct inode *inode,\ninclude/linux/shmem_fs.h-135-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n--\nmm/shmem.c=1809=bool shmem_hpage_pmd_enabled(void)\n--\nmm/shmem.c-1825-\nmm/shmem.c:1826:unsigned long shmem_allowable_huge_orders(struct inode *inode,\nmm/shmem.c-1827-\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n"
}

27/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23317
							output: 35
							thoughts: 19
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience and written in the first person:

**Diving into `mm/shmem.c` Line 1826**

Okay, so I'm thinking, let's zero in on `mm/shmem.c`, specifically around line 1826. That's usually where the core of the shared memory management functions reside, and it's a good starting point if you're looking for memory allocation or deallocation issues. I'm guessing we are looking into memory leak issues in the shared memory context.

I'll be looking for potential problems around resource handling or boundary conditions in particular. I'm going to quickly scan for calls to `kmap_atomic`, `kunmap_atomic`, `alloc_page`, `free_page`, or maybe even `vm_map`. My Spidey sense is tingling about synchronization primitives there, like spinlocks or mutexes, so I’ll pay close attention to the lock usage patterns around memory accesses. I'm also looking for possible race conditions or data corruption if multiple processes are sharing memory.



28/2 2026/07/25 06:01 tool read-file
0m Args:
{
  "File": "mm/shmem.c",
  "FirstLine": 1820,
  "LineCount": 20
}

Results:
{
  "Contents": "1820:\t\t    shmem_huge != SHMEM_HUGE_NEVER)\n1821:\t\t\treturn true;\n1822:\t\n1823:\t\treturn false;\n1824:\t}\n1825:\t\n1826:\tunsigned long shmem_allowable_huge_orders(struct inode *inode,\n1827:\t\t\t\t\tstruct vm_area_struct *vma, pgoff_t index,\n1828:\t\t\t\t\tloff_t write_end, bool shmem_huge_force)\n1829:\t{\n1830:\t\tunsigned long mask = READ_ONCE(huge_shmem_orders_always);\n1831:\t\tunsigned long within_size_orders = READ_ONCE(huge_shmem_orders_within_size);\n1832:\t\tvm_flags_t vm_flags = vma ? vma-\u003evm_flags : 0;\n1833:\t\tunsigned int global_orders, disabled_orders = 0;\n1834:\t\n1835:\t\tif (vma \u0026\u0026 vma_thp_disabled(vma, vm_flags, shmem_huge_force))\n1836:\t\t\treturn 0;\n1837:\t\n1838:\t\tif (!pgtable_has_pmd_leaves())\n1839:\t\t\tdisabled_orders = BIT(PMD_ORDER);\n"
}

29/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23967
							output: 35
							thoughts: 72
						

Thoughts:
Okay, let's see, those symbols look promising for my current investigation.

**Delving into Shared Memory and Huge Pages**

Yes, `shmem_allowable_huge_orders` seems like a solid starting point for understanding how huge page allocations are handled within shared memory. And, based on my familiarity with the kernel, I'd say `__thp_vma_allowable_orders` is another strong candidate. I'm also thinking `do_set_pmd` is likely involved in the physical memory mapping aspect, making it potentially relevant.

Now, to get a better handle on the bigger picture within the code, I'll need to see how these bits fit together. The logical next step is to examine the `shmem_parse_one` function, specifically in `mm/shmem.c`. That should give me the context I need to connect these symbols and figure out the exact flow. Time to dig in!



30/2 2026/07/25 06:01 tool read-file
0m Args:
{
  "File": "mm/shmem.c",
  "FirstLine": 4585,
  "LineCount": 20
}

Results:
{
  "Contents": "4585:\t\n4586:\t\t\t/*\n4587:\t\t\t * The requested gid must be representable in the\n4588:\t\t\t * filesystem's idmapping.\n4589:\t\t\t */\n4590:\t\t\tif (!kgid_has_mapping(fc-\u003euser_ns, kgid))\n4591:\t\t\t\tgoto bad_value;\n4592:\t\n4593:\t\t\tctx-\u003egid = kgid;\n4594:\t\t\tbreak;\n4595:\t\tcase Opt_huge:\n4596:\t\t\tctx-\u003ehuge = result.uint_32;\n4597:\t\t\tif (ctx-\u003ehuge != SHMEM_HUGE_NEVER \u0026\u0026\n4598:\t\t\t    !IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))\n4599:\t\t\t\tgoto unsupported_parameter;\n4600:\t\t\tctx-\u003eseen |= SHMEM_SEEN_HUGE;\n4601:\t\t\tbreak;\n4602:\t\tcase Opt_mpol:\n4603:\t\t\tif (IS_ENABLED(CONFIG_NUMA)) {\n4604:\t\t\t\tmpol_put(ctx-\u003empol);\n"
}

31/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 24574
							output: 20
							thoughts: 24
						

Thoughts:
Here's my thought process, as if I were analyzing that code:

**Analyzing the Shared Memory Parsing Functions**

Okay, so `shmem_parse_one` is declared as static. This immediately tells me a few things about its scope and potential use. It's only accessible within this translation unit, which implies it's an internal helper function, not intended for external linking or use in other modules. Now, the natural next step is to examine the related parsing functions to see how they fit within the code, and their relation to the static one. Let me move on to examining `shmem_parse_huge` now, to see how the other parsing functions are integrated into the shared memory parsing logic.



32/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "shmem_parse_huge"
}

Results:
{
  "Output": "mm/shmem.c=626=static unsigned int shmem_huge_global_enabled(struct inode *inode, pgoff_t index,\n--\nmm/shmem.c-669-\nmm/shmem.c:670:static int shmem_parse_huge(const char *str)\nmm/shmem.c-671-{\n--\nmm/shmem.c=5442=static ssize_t shmem_enabled_store(struct kobject *kobj,\n--\nmm/shmem.c-5454-\nmm/shmem.c:5455:\thuge = shmem_parse_huge(tmp);\nmm/shmem.c-5456-\tif (huge == -EINVAL)\n--\nmm/shmem.c=5578=static int __init setup_transparent_hugepage_shmem(char *str)\n--\nmm/shmem.c-5581-\nmm/shmem.c:5582:\thuge = shmem_parse_huge(str);\nmm/shmem.c-5583-\tif (huge == -EINVAL) {\n--\nmm/shmem.c=5593=static int __init setup_transparent_hugepage_tmpfs(char *str)\n--\nmm/shmem.c-5596-\nmm/shmem.c:5597:\thuge = shmem_parse_huge(str);\nmm/shmem.c-5598-\tif (huge \u003c 0) {\n"
}

33/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25153
							output: 23
							thoughts: 237
						

Thoughts:
**My Analysis of Potential Entry Points for Transparent Huge Pages in Shared Memory**

Okay, so I'm digging into how transparent huge pages (THP) are handled, specifically within shared memory and the tmpfs filesystem. My first thought is that `shmem_parse_huge` is static, which means it's not directly exposed as an entry point. That opens up the possibility of using related functions that are not static. I can make use of things like `shmem_allowable_huge_orders`, `__thp_vma_allowable_orders`, and `do_set_pmd`.

Then, wait a minute, I just realized `shmem_getattr` *is* static, but because it's an inode operation, it could be reachable through the `stat` syscall when operating on tmpfs. This means there's a link to the kernel that I have to consider. I need to make a note of this. Are there any other functions I may have missed?

Right, `shmem_enabled_store` is a sysfs store function, reachable by writing to `/sys/kernel/mm/transparent_hugepage/shmem_enabled`. This one is important because it's another clear entry point for configuring THP behavior. I need to keep this in mind.

However, `setup_transparent_hugepage_shmem` and `setup_transparent_hugepage_tmpfs` are both marked as `__init` functions. That means they're only executed during initialization, which is less interesting for ongoing operational considerations. The same goes for `hugepage_init_sysfs`, `hugepage_init`, and `pgtable_leaf_support_init`, all of which are `__init`.

I should probably also look at `nd_pfn_supported_alignments` in `drivers/nvdimm/pfn_devs.c`. It is probably related to hugepages in the non-volatile memory device driver.

So the main points are the functions that aren't init, and sysfs.



34/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "nd_pfn_supported_alignments"
}

Results:
{
  "Output": "drivers/nvdimm/pfn_devs.c=84=static ssize_t align_show(struct device *dev,\n--\ndrivers/nvdimm/pfn_devs.c-91-\ndrivers/nvdimm/pfn_devs.c:92:static unsigned long *nd_pfn_supported_alignments(unsigned long *alignments)\ndrivers/nvdimm/pfn_devs.c-93-{\n--\ndrivers/nvdimm/pfn_devs.c=119=static ssize_t align_store(struct device *dev,\n--\ndrivers/nvdimm/pfn_devs.c-128-\trc = nd_size_select_store(dev, buf, \u0026nd_pfn-\u003ealign,\ndrivers/nvdimm/pfn_devs.c:129:\t\t\tnd_pfn_supported_alignments(aligns));\ndrivers/nvdimm/pfn_devs.c-130-\tdev_dbg(dev, \"result: %zd wrote: %s%s\", rc, buf,\n--\ndrivers/nvdimm/pfn_devs.c=243=static ssize_t supported_alignments_show(struct device *dev,\n--\ndrivers/nvdimm/pfn_devs.c-248-\treturn nd_size_select_show(0,\ndrivers/nvdimm/pfn_devs.c:249:\t\t\tnd_pfn_supported_alignments(aligns), buf);\ndrivers/nvdimm/pfn_devs.c-250-}\n--\ndrivers/nvdimm/pfn_devs.c=418=static bool nd_supported_alignment(unsigned long align)\n--\ndrivers/nvdimm/pfn_devs.c-425-\ndrivers/nvdimm/pfn_devs.c:426:\tnd_pfn_supported_alignments(supported);\ndrivers/nvdimm/pfn_devs.c-427-\tfor (i = 0; supported[i]; i++)\n"
}

35/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26364
							output: 20
							thoughts: 55
						

Thoughts:
Here's my summary, as the thought process unfolds:

**Checking DAX Alignment Details**

Okay, so I'm looking at some DAX code, specifically dealing with persistent memory and alignment. I see that `nd_pfn_supported_alignments` and `nd_pfn_default_alignment` are declared as `static`. Right, that makes sense; they're probably configuration details specific to this driver and not something that needs to be globally accessible or modified externally.

Now, I need to understand how these alignment values are used and validated within the DAX context. Where would I expect to see such checks? Ah, yes. The logical next step is to examine the `dax_align_valid` function. It's in `drivers/dax/dax-private.h`, so let's navigate there and see what it's doing. I'm expecting to find the logic that determines if a requested DAX alignment is actually supported and reasonable within the system's DAX capabilities. Let's see...



36/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "dax_align_valid"
}

Results:
{
  "Output": "drivers/dax/bus.c=1239=static ssize_t align_store(struct device *dev, struct device_attribute *attr,\n--\ndrivers/dax/bus.c-1250-\ndrivers/dax/bus.c:1251:\tif (!dax_align_valid(val))\ndrivers/dax/bus.c-1252-\t\treturn -EINVAL;\n--\ndrivers/dax/dax-private.h=119=phys_addr_t dax_pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff, unsigned long size);\n--\ndrivers/dax/dax-private.h-121-#ifdef CONFIG_TRANSPARENT_HUGEPAGE\ndrivers/dax/dax-private.h:122:static inline bool dax_align_valid(unsigned long align)\ndrivers/dax/dax-private.h-123-{\n--\ndrivers/dax/dax-private.h-132-#else\ndrivers/dax/dax-private.h:133:static inline bool dax_align_valid(unsigned long align)\ndrivers/dax/dax-private.h-134-{\n"
}

37/2 2026/07/25 06:01 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26977
							output: 22
							thoughts: 400
						

Thoughts:
**Analyzing Key Functions and Configurations**

Okay, so I'm looking at this code and the first thing I notice is that `dax_align_valid` is defined inline. That's a good starting point. My initial thought is to zero in on these symbols as being the primary areas of interest, for now: `__thp_vma_allowable_orders`, `shmem_allowable_huge_orders`, and `do_set_pmd`. They look like they'll be the functions to watch.

I need to confirm if there are any other key functions I'm missing. Let's dig into `mm/debug_vm_pgtable.c`. Hmmm, all those functions listed – `pmd_basic_tests`, `pmd_advanced_tests`, etc. – appear to be `__init` functions. Probably not where the core logic lies, although they could be critical for debugging.

Alright, the main functional changes likely center around these files: `mm/huge_memory.c`, `mm/shmem.c`, and `mm/memory.c`. I need to review these modules to see what changes were made.

Let's double-check those primary functions again. Yep, `__thp_vma_allowable_orders` is global. `shmem_allowable_huge_orders` is also global. And `do_set_pmd` is global too. Good.

Now, I should consider the relevant configurations. Let's look at `CONFIG_TRANSPARENT_HUGEPAGE`, since that seems to be the main driver. What else is there? `CONFIG_SHMEM` is usually enabled by default, so it's probably not a high priority to check. I also need to check `CONFIG_DAX` for `drivers/dax/dax-private.h`, and `CONFIG_NVDIMM_PFN` for `drivers/nvdimm/pfn_devs.c`. And `CONFIG_DEBUG_VM_PGTABLE` for `mm/debug_vm_pgtable.c`.

Right, I should probably also check `CONFIG_TRANSPARENT_HUGEPAGE` in `mm/Kconfig` for the dependencies. It is likely I need to understand that fully.



38/2 2026/07/25 06:01 tool grepper
0m Args:
{
  "Expression": "config TRANSPARENT_HUGEPAGE"
}

Results:
{
  "Output": "mm/Kconfig=829=config MM_ID\n--\nmm/Kconfig-831-\nmm/Kconfig:832:menuconfig TRANSPARENT_HUGEPAGE\nmm/Kconfig-833-\tbool \"Transparent Hugepage Support\"\n--\nmm/Kconfig=850=choice\n--\nmm/Kconfig-855-\nmm/Kconfig:856:\tconfig TRANSPARENT_HUGEPAGE_ALWAYS\nmm/Kconfig-857-\t\tbool \"always\"\n--\nmm/Kconfig-862-\nmm/Kconfig:863:\tconfig TRANSPARENT_HUGEPAGE_MADVISE\nmm/Kconfig-864-\t\tbool \"madvise\"\n--\nmm/Kconfig-871-\nmm/Kconfig:872:\tconfig TRANSPARENT_HUGEPAGE_NEVER\nmm/Kconfig-873-\t\tbool \"never\"\n--\nmm/Kconfig=879=choice\n--\nmm/Kconfig-888-\nmm/Kconfig:889:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_NEVER\nmm/Kconfig-890-\t\tbool \"never\"\n--\nmm/Kconfig-898-\nmm/Kconfig:899:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ALWAYS\nmm/Kconfig-900-\t\tbool \"always\"\n--\nmm/Kconfig-906-\nmm/Kconfig:907:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_WITHIN_SIZE\nmm/Kconfig-908-\t\tbool \"within_size\"\n--\nmm/Kconfig-914-\nmm/Kconfig:915:\tconfig TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ADVISE\nmm/Kconfig-916-\t\tbool \"advise\"\n--\nmm/Kconfig=924=choice\n--\nmm/Kconfig-933-\nmm/Kconfig:934:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_NEVER\nmm/Kconfig-935-\t\tbool \"never\"\n--\nmm/Kconfig-942-\nmm/Kconfig:943:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ALWAYS\nmm/Kconfig-944-\t\tbool \"always\"\n--\nmm/Kconfig-950-\nmm/Kconfig:951:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_WITHIN_SIZE\nmm/Kconfig-952-\t\tbool \"within_size\"\n--\nmm/Kconfig-958-\nmm/Kconfig:959:\tconfig TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ADVISE\nmm/Kconfig-960-\t\tbool \"advise\"\n"
}

39/2 2026/07/25 06:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28604
							output: 153
							thoughts: 739
						

Thoughts:
**My Analysis of this Patch**

Okay, so the primary configuration item here is `TRANSPARENT_HUGEPAGE`. I'll definitely be including that in `EnableConfigs`. That's the core of what we're dealing with.

Now, let's verify that the key functions we're looking at are indeed accessible. I need to make sure they're not static and therefore not subject to unexpected scope restrictions. I've confirmed that `shmem_allowable_huge_orders` is not static; it's defined in both `include/linux/shmem_fs.h` and `mm/shmem.c`. Good. Next, `__thp_vma_allowable_orders` is also globally accessible, appearing in `include/linux/huge_mm.h` and `mm/huge_memory.c`. Finally, `do_set_pmd` is also not static; it's in `include/linux/mm.h` and `mm/memory.c`. Perfect.

I did briefly consider `shmem_getattr`, but since it's an inode operation, and it's assigned to `inode_operations.getattr`, and it's not being used, then it's fine. So I'll stick with the global functions: `shmem_allowable_huge_orders`, `__thp_vma_allowable_orders`, and `do_set_pmd`.

I went back and double-checked the function signatures just to be absolutely sure:
*   `__thp_vma_allowable_orders` is a global function.
*   `do_set_pmd` is a global function.
*   `shmem_allowable_huge_orders` is also a global function.

This patch is significant. It's fundamentally changing how THP support is detected and initialized, switching from `has_transparent_hugepage()` to `pgtable_has_pmd_leaves()`. This is core MM logic, affecting THP, shmem, dax, and nvdimm, to prevent the use of PMD and PUD orders on CPUs without PMD leaves. The code is functional, and the logic is reachable.

Therefore, `WorthFuzzing=true`.

My `FocusSymbols` will be: `__thp_vma_allowable_orders`, `shmem_allowable_huge_orders`, and `do_set_pmd`.

And again, my `EnableConfigs` will include `TRANSPARENT_HUGEPAGE`.

My reasoning is because the patch modifies how THP support is checked and initialized, replacing `has_transparent_hugepage()` with `pgtable_has_pmd_leaves()`. It modifies core MM logic (THP, shmem, dax, nvdimm) to filter out PMD and PUD orders if the CPU does not support PMD leaves. This is functional and reachable.



40/2 2026/07/25 06:02 tool set-results
0m Args:
{
  "EnableConfigs": [
    "TRANSPARENT_HUGEPAGE"
  ],
  "FocusSymbols": [
    "__thp_vma_allowable_orders",
    "shmem_allowable_huge_orders",
    "do_set_pmd"
  ],
  "Reasoning": "The patch modifies how THP support is checked and initialized, replacing `has_transparent_hugepage()` with `pgtable_has_pmd_leaves()`. It modifies core MM logic (THP, shmem, dax, nvdimm) to filter out PMD and PUD orders if the CPU does not support PMD leaves. This is functional and reachable.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "TRANSPARENT_HUGEPAGE"
  ],
  "FocusSymbols": [
    "__thp_vma_allowable_orders",
    "shmem_allowable_huge_orders",
    "do_set_pmd"
  ],
  "Reasoning": "The patch modifies how THP support is checked and initialized, replacing `has_transparent_hugepage()` with `pgtable_has_pmd_leaves()`. It modifies core MM logic (THP, shmem, dax, nvdimm) to filter out PMD and PUD orders if the CPU does not support PMD leaves. This is functional and reachable.",
  "WorthFuzzing": true
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)