* [PATCH RFC 0/2] mm: add huge pfnmap support for remap_pfn_range()
@ 2025-09-23 13:31 ` Yin Tirui
0 siblings, 0 replies; 21+ messages in thread
From: Yin Tirui @ 2025-09-23 13:31 UTC (permalink / raw)
To: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb,
mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua,
catalin.marinas, will, paul.walmsley, palmer, aou, alex,
anshuman.khandual, yangyicong, ardb, willy, apopple,
samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm,
linux-kernel, linux-arm-kernel, linux-riscv
Cc: wangkefeng.wang, chenjun102, yintirui
Overview
========
This patch series adds huge page support for remap_pfn_range(),
automatically creating huge mappings when prerequisites are satisfied
(size, alignment, architecture support, etc.) and falling back to
normal page mappings otherwise.
This work builds on Peter Xu's previous efforts on huge pfnmap
support [0].
TODO
====
- Add PUD-level huge page support. Currently, only PMD-level huge
pages are supported.
- Consider the logic related to vmap_page_range and extract
reusable common code.
Tests Done
==========
- Cross-build tests.
- Performance tests with custom device driver implementing mmap()
with remap_pfn_range():
- lat_mem_rd benchmark modified to use mmap(device_fd) instead of
malloc() shows around 40% improvement in memory access latency with
huge page support compared to normal page mappings.
numactl -C 0 lat_mem_rd -t 4096M (stride=64)
Memory Size (MB) Without Huge Mapping With Huge Mapping Improvement
---------------- ----------------- -------------- -----------
64.00 148.858 ns 100.780 ns 32.3%
128.00 164.745 ns 103.537 ns 37.2%
256.00 169.907 ns 103.179 ns 39.3%
512.00 171.285 ns 103.072 ns 39.8%
1024.00 173.054 ns 103.055 ns 40.4%
2048.00 172.820 ns 103.091 ns 40.3%
4096.00 172.877 ns 103.115 ns 40.4%
- Custom memory copy operations on mmap(device_fd) show around 18% performance
improvement with huge page support compared to normal page mappings.
numactl -C 0 memcpy_test (memory copy performance test)
Memory Size (MB) Without Huge Mapping With Huge Mapping Improvement
---------------- ----------------- -------------- -----------
1024.00 95.76 ms 77.91 ms 18.6%
2048.00 190.87 ms 155.64 ms 18.5%
4096.00 380.84 ms 311.45 ms 18.2%
[0] https://lore.kernel.org/all/20240826204353.2228736-2-peterx@redhat.com/T/#u
Yin Tirui (2):
pgtable: add pte_clrhuge() implementation for arm64 and riscv
mm: add PMD-level huge page support for remap_pfn_range()
arch/arm64/include/asm/pgtable.h | 8 ++++
arch/riscv/include/asm/pgtable.h | 5 +++
include/linux/pgtable.h | 6 ++-
mm/huge_memory.c | 22 +++++++---
mm/memory.c | 74 ++++++++++++++++++++++++++++----
5 files changed, 98 insertions(+), 17 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH RFC 0/2] mm: add huge pfnmap support for remap_pfn_range() @ 2025-09-23 13:31 ` Yin Tirui 0 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-23 13:31 UTC (permalink / raw) To: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102, yintirui Overview ======== This patch series adds huge page support for remap_pfn_range(), automatically creating huge mappings when prerequisites are satisfied (size, alignment, architecture support, etc.) and falling back to normal page mappings otherwise. This work builds on Peter Xu's previous efforts on huge pfnmap support [0]. TODO ==== - Add PUD-level huge page support. Currently, only PMD-level huge pages are supported. - Consider the logic related to vmap_page_range and extract reusable common code. Tests Done ========== - Cross-build tests. - Performance tests with custom device driver implementing mmap() with remap_pfn_range(): - lat_mem_rd benchmark modified to use mmap(device_fd) instead of malloc() shows around 40% improvement in memory access latency with huge page support compared to normal page mappings. numactl -C 0 lat_mem_rd -t 4096M (stride=64) Memory Size (MB) Without Huge Mapping With Huge Mapping Improvement ---------------- ----------------- -------------- ----------- 64.00 148.858 ns 100.780 ns 32.3% 128.00 164.745 ns 103.537 ns 37.2% 256.00 169.907 ns 103.179 ns 39.3% 512.00 171.285 ns 103.072 ns 39.8% 1024.00 173.054 ns 103.055 ns 40.4% 2048.00 172.820 ns 103.091 ns 40.3% 4096.00 172.877 ns 103.115 ns 40.4% - Custom memory copy operations on mmap(device_fd) show around 18% performance improvement with huge page support compared to normal page mappings. numactl -C 0 memcpy_test (memory copy performance test) Memory Size (MB) Without Huge Mapping With Huge Mapping Improvement ---------------- ----------------- -------------- ----------- 1024.00 95.76 ms 77.91 ms 18.6% 2048.00 190.87 ms 155.64 ms 18.5% 4096.00 380.84 ms 311.45 ms 18.2% [0] https://lore.kernel.org/all/20240826204353.2228736-2-peterx@redhat.com/T/#u Yin Tirui (2): pgtable: add pte_clrhuge() implementation for arm64 and riscv mm: add PMD-level huge page support for remap_pfn_range() arch/arm64/include/asm/pgtable.h | 8 ++++ arch/riscv/include/asm/pgtable.h | 5 +++ include/linux/pgtable.h | 6 ++- mm/huge_memory.c | 22 +++++++--- mm/memory.c | 74 ++++++++++++++++++++++++++++---- 5 files changed, 98 insertions(+), 17 deletions(-) -- 2.43.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 1/2] pgtable: add pte_clrhuge() implementation for arm64 and riscv 2025-09-23 13:31 ` Yin Tirui @ 2025-09-23 13:31 ` Yin Tirui -1 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-23 13:31 UTC (permalink / raw) To: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102, yintirui Add pte_clrhuge() helper function for architectures that enable ARCH_SUPPORTS_HUGE_PFNMAP to clear huge page attributes from PTE entries. This function provides the inverse operation of pte_mkhuge() and will be needed for upcoming huge page splitting, where PTE entries derived from huge page mappings need to have their huge page attributes cleared. Signed-off-by: Yin Tirui <yintirui@huawei.com> --- arch/arm64/include/asm/pgtable.h | 8 ++++++++ arch/riscv/include/asm/pgtable.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index abd2dee416b3..244755bad46f 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -366,6 +366,14 @@ static inline pte_t pte_mkinvalid(pte_t pte) return pte; } +static inline pte_t pte_clrhuge(pte_t pte) +{ + pteval_t mask = PTE_TYPE_MASK & ~PTE_VALID; + pteval_t val = PTE_TYPE_PAGE & ~PTE_VALID; + + return __pte((pte_val(pte) & ~mask) | val); +} + static inline pmd_t pmd_mkcont(pmd_t pmd) { return __pmd(pmd_val(pmd) | PMD_SECT_CONT); diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 91697fbf1f90..125b241e6d2c 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -455,6 +455,11 @@ static inline pte_t pte_mkhuge(pte_t pte) return pte; } +static inline pte_t pte_clrhuge(pte_t pte) +{ + return pte; +} + #ifdef CONFIG_RISCV_ISA_SVNAPOT #define pte_leaf_size(pte) (pte_napot(pte) ? \ napot_cont_size(napot_cont_order(pte)) :\ -- 2.43.0 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RFC 1/2] pgtable: add pte_clrhuge() implementation for arm64 and riscv @ 2025-09-23 13:31 ` Yin Tirui 0 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-23 13:31 UTC (permalink / raw) To: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102, yintirui Add pte_clrhuge() helper function for architectures that enable ARCH_SUPPORTS_HUGE_PFNMAP to clear huge page attributes from PTE entries. This function provides the inverse operation of pte_mkhuge() and will be needed for upcoming huge page splitting, where PTE entries derived from huge page mappings need to have their huge page attributes cleared. Signed-off-by: Yin Tirui <yintirui@huawei.com> --- arch/arm64/include/asm/pgtable.h | 8 ++++++++ arch/riscv/include/asm/pgtable.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index abd2dee416b3..244755bad46f 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -366,6 +366,14 @@ static inline pte_t pte_mkinvalid(pte_t pte) return pte; } +static inline pte_t pte_clrhuge(pte_t pte) +{ + pteval_t mask = PTE_TYPE_MASK & ~PTE_VALID; + pteval_t val = PTE_TYPE_PAGE & ~PTE_VALID; + + return __pte((pte_val(pte) & ~mask) | val); +} + static inline pmd_t pmd_mkcont(pmd_t pmd) { return __pmd(pmd_val(pmd) | PMD_SECT_CONT); diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 91697fbf1f90..125b241e6d2c 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -455,6 +455,11 @@ static inline pte_t pte_mkhuge(pte_t pte) return pte; } +static inline pte_t pte_clrhuge(pte_t pte) +{ + return pte; +} + #ifdef CONFIG_RISCV_ISA_SVNAPOT #define pte_leaf_size(pte) (pte_napot(pte) ? \ napot_cont_size(napot_cont_order(pte)) :\ -- 2.43.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() 2025-09-23 13:31 ` Yin Tirui @ 2025-09-23 13:31 ` Yin Tirui -1 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-23 13:31 UTC (permalink / raw) To: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102, yintirui Add PMD-level huge page support to remap_pfn_range(), automatically creating huge mappings when prerequisites are satisfied (size, alignment, architecture support, etc.) and falling back to normal page mappings otherwise. Implement special huge PMD splitting by utilizing the pgtable deposit/ withdraw mechanism. When splitting is needed, the deposited pgtable is withdrawn and populated with individual PTEs created from the original huge mapping, using pte_clrhuge() to clear huge page attributes. Update arch_needs_pgtable_deposit() to return true when PMD pfnmap support is enabled, ensuring proper pgtable management for huge pfnmap operations. Introduce pfnmap_max_page_shift parameter to control maximum page size and "nohugepfnmap" boot option to disable huge pfnmap entirely. Signed-off-by: Yin Tirui <yintirui@huawei.com> --- include/linux/pgtable.h | 6 +++- mm/huge_memory.c | 22 ++++++++---- mm/memory.c | 74 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 85 insertions(+), 17 deletions(-) diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 4c035637eeb7..4028318552ca 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -1025,7 +1025,11 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); #endif #ifndef arch_needs_pgtable_deposit -#define arch_needs_pgtable_deposit() (false) +#define arch_needs_pgtable_deposit arch_needs_pgtable_deposit +static inline bool arch_needs_pgtable_deposit(void) +{ + return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP); +} #endif #ifdef CONFIG_TRANSPARENT_HUGEPAGE diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 9c38a95e9f09..9f20adcbbb55 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2857,14 +2857,22 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, if (!vma_is_anonymous(vma)) { old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); - /* - * We are going to unmap this huge page. So - * just go ahead and zap it - */ - if (arch_needs_pgtable_deposit()) - zap_deposited_table(mm, pmd); - if (!vma_is_dax(vma) && vma_is_special_huge(vma)) + if (!vma_is_dax(vma) && vma_is_special_huge(vma)) { + pte_t entry; + + pgtable = pgtable_trans_huge_withdraw(mm, pmd); + if (unlikely(!pgtable)) + return; + pmd_populate(mm, &_pmd, pgtable); + pte = pte_offset_map(&_pmd, haddr); + entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); + set_ptes(mm, haddr, pte, entry, HPAGE_PMD_NR); + pte_unmap(pte); + + smp_wmb(); /* make pte visible before pmd */ + pmd_populate(mm, pmd, pgtable); return; + } if (unlikely(is_pmd_migration_entry(old_pmd))) { swp_entry_t entry; diff --git a/mm/memory.c b/mm/memory.c index 0ba4f6b71847..c4aaf3bd9cad 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2674,6 +2674,19 @@ vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma, return __vm_insert_mixed(vma, addr, pfn, true); } +#ifdef CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP +static unsigned int __ro_after_init pfnmap_max_page_shift = BITS_PER_LONG - 1; + +static int __init set_nohugepfnmap(char *str) +{ + pfnmap_max_page_shift = PAGE_SHIFT; + return 0; +} +early_param("nohugepfnmap", set_nohugepfnmap); +#else /* CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP */ +static const unsigned int pfnmap_max_page_shift = PAGE_SHIFT; +#endif /* CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP */ + /* * maps a range of physical memory into the requested pages. the old * mappings are removed. any references to nonexistent pages results @@ -2705,9 +2718,47 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd, return err; } +#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP +static int remap_try_huge_pmd(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, + unsigned long pfn, pgprot_t prot, + unsigned int page_shift) +{ + pgtable_t pgtable; + spinlock_t *ptl; + + if (page_shift < PMD_SHIFT) + return 0; + + if ((end - addr) != PMD_SIZE) + return 0; + + if (!IS_ALIGNED(addr, PMD_SIZE)) + return 0; + + if (!IS_ALIGNED(pfn, 1 << (PMD_SHIFT - PAGE_SHIFT))) + return 0; + + if (pmd_present(*pmd) && !pmd_free_pte_page(pmd, addr)) + return 0; + + set_pmd_at(mm, addr, pmd, pmd_mkspecial(pmd_mkhuge(pfn_pmd(pfn, prot)))); + + pgtable = pte_alloc_one(mm); + if (unlikely(!pgtable)) + return 1; + mm_inc_nr_ptes(mm); + ptl = pmd_lock(mm, pmd); + pgtable_trans_huge_deposit(mm, pmd, pgtable); + spin_unlock(ptl); + + return 1; +} +#endif + static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud, unsigned long addr, unsigned long end, - unsigned long pfn, pgprot_t prot) + unsigned long pfn, pgprot_t prot, unsigned int max_page_shift) { pmd_t *pmd; unsigned long next; @@ -2720,6 +2771,12 @@ static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud, VM_BUG_ON(pmd_trans_huge(*pmd)); do { next = pmd_addr_end(addr, end); +#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP + if (remap_try_huge_pmd(mm, pmd, addr, next, + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift)) { + continue; + } +#endif err = remap_pte_range(mm, pmd, addr, next, pfn + (addr >> PAGE_SHIFT), prot); if (err) @@ -2730,7 +2787,7 @@ static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud, static inline int remap_pud_range(struct mm_struct *mm, p4d_t *p4d, unsigned long addr, unsigned long end, - unsigned long pfn, pgprot_t prot) + unsigned long pfn, pgprot_t prot, unsigned int max_page_shift) { pud_t *pud; unsigned long next; @@ -2743,7 +2800,7 @@ static inline int remap_pud_range(struct mm_struct *mm, p4d_t *p4d, do { next = pud_addr_end(addr, end); err = remap_pmd_range(mm, pud, addr, next, - pfn + (addr >> PAGE_SHIFT), prot); + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift); if (err) return err; } while (pud++, addr = next, addr != end); @@ -2752,7 +2809,7 @@ static inline int remap_pud_range(struct mm_struct *mm, p4d_t *p4d, static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd, unsigned long addr, unsigned long end, - unsigned long pfn, pgprot_t prot) + unsigned long pfn, pgprot_t prot, unsigned int max_page_shift) { p4d_t *p4d; unsigned long next; @@ -2765,7 +2822,7 @@ static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd, do { next = p4d_addr_end(addr, end); err = remap_pud_range(mm, p4d, addr, next, - pfn + (addr >> PAGE_SHIFT), prot); + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift); if (err) return err; } while (p4d++, addr = next, addr != end); @@ -2773,7 +2830,7 @@ static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd, } static int remap_pfn_range_internal(struct vm_area_struct *vma, unsigned long addr, - unsigned long pfn, unsigned long size, pgprot_t prot) + unsigned long pfn, unsigned long size, pgprot_t prot, unsigned int max_page_shift) { pgd_t *pgd; unsigned long next; @@ -2817,7 +2874,7 @@ static int remap_pfn_range_internal(struct vm_area_struct *vma, unsigned long ad do { next = pgd_addr_end(addr, end); err = remap_p4d_range(mm, pgd, addr, next, - pfn + (addr >> PAGE_SHIFT), prot); + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift); if (err) return err; } while (pgd++, addr = next, addr != end); @@ -2832,8 +2889,7 @@ static int remap_pfn_range_internal(struct vm_area_struct *vma, unsigned long ad int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot) { - int error = remap_pfn_range_internal(vma, addr, pfn, size, prot); - + int error = remap_pfn_range_internal(vma, addr, pfn, size, prot, pfnmap_max_page_shift); if (!error) return 0; -- 2.43.0 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() @ 2025-09-23 13:31 ` Yin Tirui 0 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-23 13:31 UTC (permalink / raw) To: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102, yintirui Add PMD-level huge page support to remap_pfn_range(), automatically creating huge mappings when prerequisites are satisfied (size, alignment, architecture support, etc.) and falling back to normal page mappings otherwise. Implement special huge PMD splitting by utilizing the pgtable deposit/ withdraw mechanism. When splitting is needed, the deposited pgtable is withdrawn and populated with individual PTEs created from the original huge mapping, using pte_clrhuge() to clear huge page attributes. Update arch_needs_pgtable_deposit() to return true when PMD pfnmap support is enabled, ensuring proper pgtable management for huge pfnmap operations. Introduce pfnmap_max_page_shift parameter to control maximum page size and "nohugepfnmap" boot option to disable huge pfnmap entirely. Signed-off-by: Yin Tirui <yintirui@huawei.com> --- include/linux/pgtable.h | 6 +++- mm/huge_memory.c | 22 ++++++++---- mm/memory.c | 74 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 85 insertions(+), 17 deletions(-) diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 4c035637eeb7..4028318552ca 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -1025,7 +1025,11 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); #endif #ifndef arch_needs_pgtable_deposit -#define arch_needs_pgtable_deposit() (false) +#define arch_needs_pgtable_deposit arch_needs_pgtable_deposit +static inline bool arch_needs_pgtable_deposit(void) +{ + return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP); +} #endif #ifdef CONFIG_TRANSPARENT_HUGEPAGE diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 9c38a95e9f09..9f20adcbbb55 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2857,14 +2857,22 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, if (!vma_is_anonymous(vma)) { old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); - /* - * We are going to unmap this huge page. So - * just go ahead and zap it - */ - if (arch_needs_pgtable_deposit()) - zap_deposited_table(mm, pmd); - if (!vma_is_dax(vma) && vma_is_special_huge(vma)) + if (!vma_is_dax(vma) && vma_is_special_huge(vma)) { + pte_t entry; + + pgtable = pgtable_trans_huge_withdraw(mm, pmd); + if (unlikely(!pgtable)) + return; + pmd_populate(mm, &_pmd, pgtable); + pte = pte_offset_map(&_pmd, haddr); + entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); + set_ptes(mm, haddr, pte, entry, HPAGE_PMD_NR); + pte_unmap(pte); + + smp_wmb(); /* make pte visible before pmd */ + pmd_populate(mm, pmd, pgtable); return; + } if (unlikely(is_pmd_migration_entry(old_pmd))) { swp_entry_t entry; diff --git a/mm/memory.c b/mm/memory.c index 0ba4f6b71847..c4aaf3bd9cad 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2674,6 +2674,19 @@ vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma, return __vm_insert_mixed(vma, addr, pfn, true); } +#ifdef CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP +static unsigned int __ro_after_init pfnmap_max_page_shift = BITS_PER_LONG - 1; + +static int __init set_nohugepfnmap(char *str) +{ + pfnmap_max_page_shift = PAGE_SHIFT; + return 0; +} +early_param("nohugepfnmap", set_nohugepfnmap); +#else /* CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP */ +static const unsigned int pfnmap_max_page_shift = PAGE_SHIFT; +#endif /* CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP */ + /* * maps a range of physical memory into the requested pages. the old * mappings are removed. any references to nonexistent pages results @@ -2705,9 +2718,47 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd, return err; } +#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP +static int remap_try_huge_pmd(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr, unsigned long end, + unsigned long pfn, pgprot_t prot, + unsigned int page_shift) +{ + pgtable_t pgtable; + spinlock_t *ptl; + + if (page_shift < PMD_SHIFT) + return 0; + + if ((end - addr) != PMD_SIZE) + return 0; + + if (!IS_ALIGNED(addr, PMD_SIZE)) + return 0; + + if (!IS_ALIGNED(pfn, 1 << (PMD_SHIFT - PAGE_SHIFT))) + return 0; + + if (pmd_present(*pmd) && !pmd_free_pte_page(pmd, addr)) + return 0; + + set_pmd_at(mm, addr, pmd, pmd_mkspecial(pmd_mkhuge(pfn_pmd(pfn, prot)))); + + pgtable = pte_alloc_one(mm); + if (unlikely(!pgtable)) + return 1; + mm_inc_nr_ptes(mm); + ptl = pmd_lock(mm, pmd); + pgtable_trans_huge_deposit(mm, pmd, pgtable); + spin_unlock(ptl); + + return 1; +} +#endif + static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud, unsigned long addr, unsigned long end, - unsigned long pfn, pgprot_t prot) + unsigned long pfn, pgprot_t prot, unsigned int max_page_shift) { pmd_t *pmd; unsigned long next; @@ -2720,6 +2771,12 @@ static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud, VM_BUG_ON(pmd_trans_huge(*pmd)); do { next = pmd_addr_end(addr, end); +#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP + if (remap_try_huge_pmd(mm, pmd, addr, next, + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift)) { + continue; + } +#endif err = remap_pte_range(mm, pmd, addr, next, pfn + (addr >> PAGE_SHIFT), prot); if (err) @@ -2730,7 +2787,7 @@ static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud, static inline int remap_pud_range(struct mm_struct *mm, p4d_t *p4d, unsigned long addr, unsigned long end, - unsigned long pfn, pgprot_t prot) + unsigned long pfn, pgprot_t prot, unsigned int max_page_shift) { pud_t *pud; unsigned long next; @@ -2743,7 +2800,7 @@ static inline int remap_pud_range(struct mm_struct *mm, p4d_t *p4d, do { next = pud_addr_end(addr, end); err = remap_pmd_range(mm, pud, addr, next, - pfn + (addr >> PAGE_SHIFT), prot); + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift); if (err) return err; } while (pud++, addr = next, addr != end); @@ -2752,7 +2809,7 @@ static inline int remap_pud_range(struct mm_struct *mm, p4d_t *p4d, static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd, unsigned long addr, unsigned long end, - unsigned long pfn, pgprot_t prot) + unsigned long pfn, pgprot_t prot, unsigned int max_page_shift) { p4d_t *p4d; unsigned long next; @@ -2765,7 +2822,7 @@ static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd, do { next = p4d_addr_end(addr, end); err = remap_pud_range(mm, p4d, addr, next, - pfn + (addr >> PAGE_SHIFT), prot); + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift); if (err) return err; } while (p4d++, addr = next, addr != end); @@ -2773,7 +2830,7 @@ static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd, } static int remap_pfn_range_internal(struct vm_area_struct *vma, unsigned long addr, - unsigned long pfn, unsigned long size, pgprot_t prot) + unsigned long pfn, unsigned long size, pgprot_t prot, unsigned int max_page_shift) { pgd_t *pgd; unsigned long next; @@ -2817,7 +2874,7 @@ static int remap_pfn_range_internal(struct vm_area_struct *vma, unsigned long ad do { next = pgd_addr_end(addr, end); err = remap_p4d_range(mm, pgd, addr, next, - pfn + (addr >> PAGE_SHIFT), prot); + pfn + (addr >> PAGE_SHIFT), prot, max_page_shift); if (err) return err; } while (pgd++, addr = next, addr != end); @@ -2832,8 +2889,7 @@ static int remap_pfn_range_internal(struct vm_area_struct *vma, unsigned long ad int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot) { - int error = remap_pfn_range_internal(vma, addr, pfn, size, prot); - + int error = remap_pfn_range_internal(vma, addr, pfn, size, prot, pfnmap_max_page_shift); if (!error) return 0; -- 2.43.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() 2025-09-23 13:31 ` Yin Tirui @ 2025-09-23 22:39 ` Matthew Wilcox -1 siblings, 0 replies; 21+ messages in thread From: Matthew Wilcox @ 2025-09-23 22:39 UTC (permalink / raw) To: Yin Tirui Cc: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv, wangkefeng.wang, chenjun102 On Tue, Sep 23, 2025 at 09:31:04PM +0800, Yin Tirui wrote: > + entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); This doesn't make sense. And I'm not saying you got this wrong; I suspect in terms of how things work today it's actually necessary. But the way we handle this stuff is so insane. pte_clrhuge() should not exist. If we have a PTE, it can't have the huge bit set, by definition (don't anybody mention hugetlbfs because that is an entirely separate pile of broken horrors). I understand what you're trying to do here. You want to construct a PTE that points to the same address as the first page of the PMD and has the same permissions. But that *should* be written as: entry = pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); right? Now, pmd_pgprot() might or might not want to return the huge bit set. I'm not sure. Perhaps you could have a look through and figure it out. But pfn_pte() should never return a PTE with the huge bit set. So if it is set in the pgorot on entry, it should filter it out. There are going to be consequences to this. Maybe there's code somewhere that relies on pfn_pte() returning a PTE with the huge bit set. Perhaps it's hugetlbfs. But we have to start cleaning this garbage up. I did some work with e3981db444a0 and the commits leading up to that. See https://lkml.kernel.org/r/20250402181709.2386022-12-willy@infradead.org I'd like pte_clrhuge() to be deleted from x86, not added to arm and riscv. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() @ 2025-09-23 22:39 ` Matthew Wilcox 0 siblings, 0 replies; 21+ messages in thread From: Matthew Wilcox @ 2025-09-23 22:39 UTC (permalink / raw) To: Yin Tirui Cc: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv, wangkefeng.wang, chenjun102 On Tue, Sep 23, 2025 at 09:31:04PM +0800, Yin Tirui wrote: > + entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); This doesn't make sense. And I'm not saying you got this wrong; I suspect in terms of how things work today it's actually necessary. But the way we handle this stuff is so insane. pte_clrhuge() should not exist. If we have a PTE, it can't have the huge bit set, by definition (don't anybody mention hugetlbfs because that is an entirely separate pile of broken horrors). I understand what you're trying to do here. You want to construct a PTE that points to the same address as the first page of the PMD and has the same permissions. But that *should* be written as: entry = pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); right? Now, pmd_pgprot() might or might not want to return the huge bit set. I'm not sure. Perhaps you could have a look through and figure it out. But pfn_pte() should never return a PTE with the huge bit set. So if it is set in the pgorot on entry, it should filter it out. There are going to be consequences to this. Maybe there's code somewhere that relies on pfn_pte() returning a PTE with the huge bit set. Perhaps it's hugetlbfs. But we have to start cleaning this garbage up. I did some work with e3981db444a0 and the commits leading up to that. See https://lkml.kernel.org/r/20250402181709.2386022-12-willy@infradead.org I'd like pte_clrhuge() to be deleted from x86, not added to arm and riscv. _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() 2025-09-23 22:39 ` Matthew Wilcox @ 2025-09-25 2:17 ` Yin Tirui -1 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-25 2:17 UTC (permalink / raw) To: Matthew Wilcox Cc: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv, wangkefeng.wang, chenjun102 On 9/24/2025 6:39 AM, Matthew Wilcox wrote: > On Tue, Sep 23, 2025 at 09:31:04PM +0800, Yin Tirui wrote: >> + entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); > > This doesn't make sense. And I'm not saying you got this wrong; I > suspect in terms of how things work today it's actually necessary. > But the way we handle this stuff is so insane. Thank you for pointing this out and the broader context. > > pte_clrhuge() should not exist. If we have a PTE, it can't have the > huge bit set, by definition (don't anybody mention hugetlbfs because > that is an entirely separate pile of broken horrors). I understand what > you're trying to do here. You want to construct a PTE that points to > the same address as the first page of the PMD and has the same > permissions. But that *should* be written as: > > entry = pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); > > right? Now, pmd_pgprot() might or might not want to return the huge bit > set. I'm not sure. Perhaps you could have a look through and figure it I've tested this on arm64, and pmd_pgprot() does return the huge bit set, which is exactly why I added pte_clrhuge(). > out. But pfn_pte() should never return a PTE with the huge bit set. > So if it is set in the pgorot on entry, it should filter it out. > > There are going to be consequences to this. Maybe there's code > somewhere that relies on pfn_pte() returning a PTE with the huge bit > set. Perhaps it's hugetlbfs. I'll try to refactor pfn_pte() and related functions to filter out the huge bit set and test its impact on hugetlbfs. > > But we have to start cleaning this garbage up. I did some work with > e3981db444a0 and the commits leading up to that. See > https://lkml.kernel.org/r/20250402181709.2386022-12-willy@infradead.org > > I'd like pte_clrhuge() to be deleted from x86, not added to arm and > riscv. > I completely agree with the goal of deleting pte_clrhuge() rather than expanding it. I'll study your referenced work and align my approach with your efforts. Would you recommend I address the pfn_pte() and related function refactoring as part of this patch series, or should I submit it as a separate patch series? -- Best regards, Yin Tirui ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() @ 2025-09-25 2:17 ` Yin Tirui 0 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-25 2:17 UTC (permalink / raw) To: Matthew Wilcox Cc: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv, wangkefeng.wang, chenjun102 On 9/24/2025 6:39 AM, Matthew Wilcox wrote: > On Tue, Sep 23, 2025 at 09:31:04PM +0800, Yin Tirui wrote: >> + entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); > > This doesn't make sense. And I'm not saying you got this wrong; I > suspect in terms of how things work today it's actually necessary. > But the way we handle this stuff is so insane. Thank you for pointing this out and the broader context. > > pte_clrhuge() should not exist. If we have a PTE, it can't have the > huge bit set, by definition (don't anybody mention hugetlbfs because > that is an entirely separate pile of broken horrors). I understand what > you're trying to do here. You want to construct a PTE that points to > the same address as the first page of the PMD and has the same > permissions. But that *should* be written as: > > entry = pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); > > right? Now, pmd_pgprot() might or might not want to return the huge bit > set. I'm not sure. Perhaps you could have a look through and figure it I've tested this on arm64, and pmd_pgprot() does return the huge bit set, which is exactly why I added pte_clrhuge(). > out. But pfn_pte() should never return a PTE with the huge bit set. > So if it is set in the pgorot on entry, it should filter it out. > > There are going to be consequences to this. Maybe there's code > somewhere that relies on pfn_pte() returning a PTE with the huge bit > set. Perhaps it's hugetlbfs. I'll try to refactor pfn_pte() and related functions to filter out the huge bit set and test its impact on hugetlbfs. > > But we have to start cleaning this garbage up. I did some work with > e3981db444a0 and the commits leading up to that. See > https://lkml.kernel.org/r/20250402181709.2386022-12-willy@infradead.org > > I'd like pte_clrhuge() to be deleted from x86, not added to arm and > riscv. > I completely agree with the goal of deleting pte_clrhuge() rather than expanding it. I'll study your referenced work and align my approach with your efforts. Would you recommend I address the pfn_pte() and related function refactoring as part of this patch series, or should I submit it as a separate patch series? -- Best regards, Yin Tirui _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() 2025-09-23 13:31 ` Yin Tirui @ 2025-09-24 9:50 ` David Hildenbrand -1 siblings, 0 replies; 21+ messages in thread From: David Hildenbrand @ 2025-09-24 9:50 UTC (permalink / raw) To: Yin Tirui, akpm, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102 On 23.09.25 15:31, Yin Tirui wrote: > Add PMD-level huge page support to remap_pfn_range(), automatically > creating huge mappings when prerequisites are satisfied (size, alignment, > architecture support, etc.) and falling back to normal page mappings > otherwise. > > Implement special huge PMD splitting by utilizing the pgtable deposit/ > withdraw mechanism. When splitting is needed, the deposited pgtable is > withdrawn and populated with individual PTEs created from the original > huge mapping, using pte_clrhuge() to clear huge page attributes. > > Update arch_needs_pgtable_deposit() to return true when PMD pfnmap > support is enabled, ensuring proper pgtable management for huge > pfnmap operations. > > Introduce pfnmap_max_page_shift parameter to control maximum page > size and "nohugepfnmap" boot option to disable huge pfnmap entirely. Why? If an arch supports it we should just do it. Or what's the reason behind that? > > Signed-off-by: Yin Tirui <yintirui@huawei.com> > --- > include/linux/pgtable.h | 6 +++- > mm/huge_memory.c | 22 ++++++++---- > mm/memory.c | 74 ++++++++++++++++++++++++++++++++++++----- > 3 files changed, 85 insertions(+), 17 deletions(-) > > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h > index 4c035637eeb7..4028318552ca 100644 > --- a/include/linux/pgtable.h > +++ b/include/linux/pgtable.h > @@ -1025,7 +1025,11 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); > #endif > > #ifndef arch_needs_pgtable_deposit > -#define arch_needs_pgtable_deposit() (false) > +#define arch_needs_pgtable_deposit arch_needs_pgtable_deposit > +static inline bool arch_needs_pgtable_deposit(void) > +{ > + return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP); > +} > #endif > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 9c38a95e9f09..9f20adcbbb55 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2857,14 +2857,22 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, > > if (!vma_is_anonymous(vma)) { > old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); > - /* > - * We are going to unmap this huge page. So > - * just go ahead and zap it > - */ > - if (arch_needs_pgtable_deposit()) > - zap_deposited_table(mm, pmd); Are you sure we can just entirely remove this block for !vma_is_anonymous(vma)? -- Cheers David / dhildenb ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() @ 2025-09-24 9:50 ` David Hildenbrand 0 siblings, 0 replies; 21+ messages in thread From: David Hildenbrand @ 2025-09-24 9:50 UTC (permalink / raw) To: Yin Tirui, akpm, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102 On 23.09.25 15:31, Yin Tirui wrote: > Add PMD-level huge page support to remap_pfn_range(), automatically > creating huge mappings when prerequisites are satisfied (size, alignment, > architecture support, etc.) and falling back to normal page mappings > otherwise. > > Implement special huge PMD splitting by utilizing the pgtable deposit/ > withdraw mechanism. When splitting is needed, the deposited pgtable is > withdrawn and populated with individual PTEs created from the original > huge mapping, using pte_clrhuge() to clear huge page attributes. > > Update arch_needs_pgtable_deposit() to return true when PMD pfnmap > support is enabled, ensuring proper pgtable management for huge > pfnmap operations. > > Introduce pfnmap_max_page_shift parameter to control maximum page > size and "nohugepfnmap" boot option to disable huge pfnmap entirely. Why? If an arch supports it we should just do it. Or what's the reason behind that? > > Signed-off-by: Yin Tirui <yintirui@huawei.com> > --- > include/linux/pgtable.h | 6 +++- > mm/huge_memory.c | 22 ++++++++---- > mm/memory.c | 74 ++++++++++++++++++++++++++++++++++++----- > 3 files changed, 85 insertions(+), 17 deletions(-) > > diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h > index 4c035637eeb7..4028318552ca 100644 > --- a/include/linux/pgtable.h > +++ b/include/linux/pgtable.h > @@ -1025,7 +1025,11 @@ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp); > #endif > > #ifndef arch_needs_pgtable_deposit > -#define arch_needs_pgtable_deposit() (false) > +#define arch_needs_pgtable_deposit arch_needs_pgtable_deposit > +static inline bool arch_needs_pgtable_deposit(void) > +{ > + return IS_ENABLED(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP); > +} > #endif > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 9c38a95e9f09..9f20adcbbb55 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2857,14 +2857,22 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, > > if (!vma_is_anonymous(vma)) { > old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); > - /* > - * We are going to unmap this huge page. So > - * just go ahead and zap it > - */ > - if (arch_needs_pgtable_deposit()) > - zap_deposited_table(mm, pmd); Are you sure we can just entirely remove this block for !vma_is_anonymous(vma)? -- Cheers David / dhildenb _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() 2025-09-24 9:50 ` David Hildenbrand @ 2025-09-25 1:43 ` Yin Tirui -1 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-25 1:43 UTC (permalink / raw) To: David Hildenbrand, akpm, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102 On 9/24/2025 5:50 PM, David Hildenbrand wrote: >> Introduce pfnmap_max_page_shift parameter to control maximum page >> size and "nohugepfnmap" boot option to disable huge pfnmap entirely. > > Why? If an arch supports it we should just do it. Or what's the reason > behind that? > There's no specific reason for this - it was just intended to provide an additional option. I'll remove it in the next version. ... > Are you sure we can just entirely remove this block for ! > vma_is_anonymous(vma)? > Thank you for pointing this out! There is definitely a problem with removing this block entirely for non-anonymous VMAs. I've also found some other problems. I'll fix all of them in the next version. -- Best regards, Yin Tirui ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() @ 2025-09-25 1:43 ` Yin Tirui 0 siblings, 0 replies; 21+ messages in thread From: Yin Tirui @ 2025-09-25 1:43 UTC (permalink / raw) To: David Hildenbrand, akpm, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102 On 9/24/2025 5:50 PM, David Hildenbrand wrote: >> Introduce pfnmap_max_page_shift parameter to control maximum page >> size and "nohugepfnmap" boot option to disable huge pfnmap entirely. > > Why? If an arch supports it we should just do it. Or what's the reason > behind that? > There's no specific reason for this - it was just intended to provide an additional option. I'll remove it in the next version. ... > Are you sure we can just entirely remove this block for ! > vma_is_anonymous(vma)? > Thank you for pointing this out! There is definitely a problem with removing this block entirely for non-anonymous VMAs. I've also found some other problems. I'll fix all of them in the next version. -- Best regards, Yin Tirui _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() 2025-09-25 1:43 ` Yin Tirui @ 2025-09-25 9:38 ` David Hildenbrand -1 siblings, 0 replies; 21+ messages in thread From: David Hildenbrand @ 2025-09-25 9:38 UTC (permalink / raw) To: Yin Tirui, akpm, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102 On 25.09.25 03:43, Yin Tirui wrote: > > > On 9/24/2025 5:50 PM, David Hildenbrand wrote: >>> Introduce pfnmap_max_page_shift parameter to control maximum page >>> size and "nohugepfnmap" boot option to disable huge pfnmap entirely. >> >> Why? If an arch supports it we should just do it. Or what's the reason >> behind that? >> > There's no specific reason for this - it was just intended to provide an > additional option. I'll remove it in the next version. Good, then let's keep it simple :) -- Cheers David / dhildenb ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() @ 2025-09-25 9:38 ` David Hildenbrand 0 siblings, 0 replies; 21+ messages in thread From: David Hildenbrand @ 2025-09-25 9:38 UTC (permalink / raw) To: Yin Tirui, akpm, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb, mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua, catalin.marinas, will, paul.walmsley, palmer, aou, alex, anshuman.khandual, yangyicong, ardb, willy, apopple, samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm, linux-kernel, linux-arm-kernel, linux-riscv Cc: wangkefeng.wang, chenjun102 On 25.09.25 03:43, Yin Tirui wrote: > > > On 9/24/2025 5:50 PM, David Hildenbrand wrote: >>> Introduce pfnmap_max_page_shift parameter to control maximum page >>> size and "nohugepfnmap" boot option to disable huge pfnmap entirely. >> >> Why? If an arch supports it we should just do it. Or what's the reason >> behind that? >> > There's no specific reason for this - it was just intended to provide an > additional option. I'll remove it in the next version. Good, then let's keep it simple :) -- Cheers David / dhildenb _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() 2025-09-23 13:31 ` Yin Tirui ` (2 preceding siblings ...) (?) @ 2025-09-25 3:14 ` kernel test robot -1 siblings, 0 replies; 21+ messages in thread From: kernel test robot @ 2025-09-25 3:14 UTC (permalink / raw) To: Yin Tirui; +Cc: oe-kbuild-all Hi Yin, [This is a private test report for your RFC patch.] kernel test robot noticed the following build errors: [auto build test ERROR on arm64/for-next/core] [also build test ERROR on soc/for-next linus/master v6.17-rc7 next-20250924] [cannot apply to akpm-mm/mm-everything] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Yin-Tirui/pgtable-add-pte_clrhuge-implementation-for-arm64-and-riscv/20250923-213919 base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core patch link: https://lore.kernel.org/r/20250923133104.926672-3-yintirui%40huawei.com patch subject: [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() config: s390-randconfig-002-20250925 (https://download.01.org/0day-ci/archive/20250925/202509251011.a6EgAfsn-lkp@intel.com/config) compiler: s390-linux-gcc (GCC) 13.4.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250925/202509251011.a6EgAfsn-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202509251011.a6EgAfsn-lkp@intel.com/ All errors (new ones prefixed by >>): mm/huge_memory.c: In function '__split_huge_pmd_locked': >> mm/huge_memory.c:2868:33: error: implicit declaration of function 'pte_clrhuge'; did you mean 'pte_mkhuge'? [-Werror=implicit-function-declaration] 2868 | entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); | ^~~~~~~~~~~ | pte_mkhuge >> mm/huge_memory.c:2868:33: error: incompatible types when assigning to type 'pte_t' from type 'int' cc1: some warnings being treated as errors vim +2868 mm/huge_memory.c 2836 2837 static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, 2838 unsigned long haddr, bool freeze) 2839 { 2840 struct mm_struct *mm = vma->vm_mm; 2841 struct folio *folio; 2842 struct page *page; 2843 pgtable_t pgtable; 2844 pmd_t old_pmd, _pmd; 2845 bool young, write, soft_dirty, pmd_migration = false, uffd_wp = false; 2846 bool anon_exclusive = false, dirty = false; 2847 unsigned long addr; 2848 pte_t *pte; 2849 int i; 2850 2851 VM_BUG_ON(haddr & ~HPAGE_PMD_MASK); 2852 VM_BUG_ON_VMA(vma->vm_start > haddr, vma); 2853 VM_BUG_ON_VMA(vma->vm_end < haddr + HPAGE_PMD_SIZE, vma); 2854 VM_BUG_ON(!is_pmd_migration_entry(*pmd) && !pmd_trans_huge(*pmd)); 2855 2856 count_vm_event(THP_SPLIT_PMD); 2857 2858 if (!vma_is_anonymous(vma)) { 2859 old_pmd = pmdp_huge_clear_flush(vma, haddr, pmd); 2860 if (!vma_is_dax(vma) && vma_is_special_huge(vma)) { 2861 pte_t entry; 2862 2863 pgtable = pgtable_trans_huge_withdraw(mm, pmd); 2864 if (unlikely(!pgtable)) 2865 return; 2866 pmd_populate(mm, &_pmd, pgtable); 2867 pte = pte_offset_map(&_pmd, haddr); > 2868 entry = pte_clrhuge(pfn_pte(pmd_pfn(old_pmd), pmd_pgprot(old_pmd))); 2869 set_ptes(mm, haddr, pte, entry, HPAGE_PMD_NR); 2870 pte_unmap(pte); 2871 2872 smp_wmb(); /* make pte visible before pmd */ 2873 pmd_populate(mm, pmd, pgtable); 2874 return; 2875 } 2876 if (unlikely(is_pmd_migration_entry(old_pmd))) { 2877 swp_entry_t entry; 2878 2879 entry = pmd_to_swp_entry(old_pmd); 2880 folio = pfn_swap_entry_folio(entry); 2881 } else if (is_huge_zero_pmd(old_pmd)) { 2882 return; 2883 } else { 2884 page = pmd_page(old_pmd); 2885 folio = page_folio(page); 2886 if (!folio_test_dirty(folio) && pmd_dirty(old_pmd)) 2887 folio_mark_dirty(folio); 2888 if (!folio_test_referenced(folio) && pmd_young(old_pmd)) 2889 folio_set_referenced(folio); 2890 folio_remove_rmap_pmd(folio, page, vma); 2891 folio_put(folio); 2892 } 2893 add_mm_counter(mm, mm_counter_file(folio), -HPAGE_PMD_NR); 2894 return; 2895 } 2896 2897 if (is_huge_zero_pmd(*pmd)) { 2898 /* 2899 * FIXME: Do we want to invalidate secondary mmu by calling 2900 * mmu_notifier_arch_invalidate_secondary_tlbs() see comments below 2901 * inside __split_huge_pmd() ? 2902 * 2903 * We are going from a zero huge page write protected to zero 2904 * small page also write protected so it does not seems useful 2905 * to invalidate secondary mmu at this time. 2906 */ 2907 return __split_huge_zero_page_pmd(vma, haddr, pmd); 2908 } 2909 2910 pmd_migration = is_pmd_migration_entry(*pmd); 2911 if (unlikely(pmd_migration)) { 2912 swp_entry_t entry; 2913 2914 old_pmd = *pmd; 2915 entry = pmd_to_swp_entry(old_pmd); 2916 page = pfn_swap_entry_to_page(entry); 2917 write = is_writable_migration_entry(entry); 2918 if (PageAnon(page)) 2919 anon_exclusive = is_readable_exclusive_migration_entry(entry); 2920 young = is_migration_entry_young(entry); 2921 dirty = is_migration_entry_dirty(entry); 2922 soft_dirty = pmd_swp_soft_dirty(old_pmd); 2923 uffd_wp = pmd_swp_uffd_wp(old_pmd); 2924 } else { 2925 /* 2926 * Up to this point the pmd is present and huge and userland has 2927 * the whole access to the hugepage during the split (which 2928 * happens in place). If we overwrite the pmd with the not-huge 2929 * version pointing to the pte here (which of course we could if 2930 * all CPUs were bug free), userland could trigger a small page 2931 * size TLB miss on the small sized TLB while the hugepage TLB 2932 * entry is still established in the huge TLB. Some CPU doesn't 2933 * like that. See 2934 * http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf, Erratum 2935 * 383 on page 105. Intel should be safe but is also warns that 2936 * it's only safe if the permission and cache attributes of the 2937 * two entries loaded in the two TLB is identical (which should 2938 * be the case here). But it is generally safer to never allow 2939 * small and huge TLB entries for the same virtual address to be 2940 * loaded simultaneously. So instead of doing "pmd_populate(); 2941 * flush_pmd_tlb_range();" we first mark the current pmd 2942 * notpresent (atomically because here the pmd_trans_huge must 2943 * remain set at all times on the pmd until the split is 2944 * complete for this pmd), then we flush the SMP TLB and finally 2945 * we write the non-huge version of the pmd entry with 2946 * pmd_populate. 2947 */ 2948 old_pmd = pmdp_invalidate(vma, haddr, pmd); 2949 page = pmd_page(old_pmd); 2950 folio = page_folio(page); 2951 if (pmd_dirty(old_pmd)) { 2952 dirty = true; 2953 folio_set_dirty(folio); 2954 } 2955 write = pmd_write(old_pmd); 2956 young = pmd_young(old_pmd); 2957 soft_dirty = pmd_soft_dirty(old_pmd); 2958 uffd_wp = pmd_uffd_wp(old_pmd); 2959 2960 VM_WARN_ON_FOLIO(!folio_ref_count(folio), folio); 2961 VM_WARN_ON_FOLIO(!folio_test_anon(folio), folio); 2962 2963 /* 2964 * Without "freeze", we'll simply split the PMD, propagating the 2965 * PageAnonExclusive() flag for each PTE by setting it for 2966 * each subpage -- no need to (temporarily) clear. 2967 * 2968 * With "freeze" we want to replace mapped pages by 2969 * migration entries right away. This is only possible if we 2970 * managed to clear PageAnonExclusive() -- see 2971 * set_pmd_migration_entry(). 2972 * 2973 * In case we cannot clear PageAnonExclusive(), split the PMD 2974 * only and let try_to_migrate_one() fail later. 2975 * 2976 * See folio_try_share_anon_rmap_pmd(): invalidate PMD first. 2977 */ 2978 anon_exclusive = PageAnonExclusive(page); 2979 if (freeze && anon_exclusive && 2980 folio_try_share_anon_rmap_pmd(folio, page)) 2981 freeze = false; 2982 if (!freeze) { 2983 rmap_t rmap_flags = RMAP_NONE; 2984 2985 folio_ref_add(folio, HPAGE_PMD_NR - 1); 2986 if (anon_exclusive) 2987 rmap_flags |= RMAP_EXCLUSIVE; 2988 folio_add_anon_rmap_ptes(folio, page, HPAGE_PMD_NR, 2989 vma, haddr, rmap_flags); 2990 } 2991 } 2992 2993 /* 2994 * Withdraw the table only after we mark the pmd entry invalid. 2995 * This's critical for some architectures (Power). 2996 */ 2997 pgtable = pgtable_trans_huge_withdraw(mm, pmd); 2998 pmd_populate(mm, &_pmd, pgtable); 2999 3000 pte = pte_offset_map(&_pmd, haddr); 3001 VM_BUG_ON(!pte); 3002 3003 /* 3004 * Note that NUMA hinting access restrictions are not transferred to 3005 * avoid any possibility of altering permissions across VMAs. 3006 */ 3007 if (freeze || pmd_migration) { 3008 for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) { 3009 pte_t entry; 3010 swp_entry_t swp_entry; 3011 3012 if (write) 3013 swp_entry = make_writable_migration_entry( 3014 page_to_pfn(page + i)); 3015 else if (anon_exclusive) 3016 swp_entry = make_readable_exclusive_migration_entry( 3017 page_to_pfn(page + i)); 3018 else 3019 swp_entry = make_readable_migration_entry( 3020 page_to_pfn(page + i)); 3021 if (young) 3022 swp_entry = make_migration_entry_young(swp_entry); 3023 if (dirty) 3024 swp_entry = make_migration_entry_dirty(swp_entry); 3025 entry = swp_entry_to_pte(swp_entry); 3026 if (soft_dirty) 3027 entry = pte_swp_mksoft_dirty(entry); 3028 if (uffd_wp) 3029 entry = pte_swp_mkuffd_wp(entry); 3030 3031 VM_WARN_ON(!pte_none(ptep_get(pte + i))); 3032 set_pte_at(mm, addr, pte + i, entry); 3033 } 3034 } else { 3035 pte_t entry; 3036 3037 entry = mk_pte(page, READ_ONCE(vma->vm_page_prot)); 3038 if (write) 3039 entry = pte_mkwrite(entry, vma); 3040 if (!young) 3041 entry = pte_mkold(entry); 3042 /* NOTE: this may set soft-dirty too on some archs */ 3043 if (dirty) 3044 entry = pte_mkdirty(entry); 3045 if (soft_dirty) 3046 entry = pte_mksoft_dirty(entry); 3047 if (uffd_wp) 3048 entry = pte_mkuffd_wp(entry); 3049 3050 for (i = 0; i < HPAGE_PMD_NR; i++) 3051 VM_WARN_ON(!pte_none(ptep_get(pte + i))); 3052 3053 set_ptes(mm, haddr, pte, entry, HPAGE_PMD_NR); 3054 } 3055 pte_unmap(pte); 3056 3057 if (!pmd_migration) 3058 folio_remove_rmap_pmd(folio, page, vma); 3059 if (freeze) 3060 put_page(page); 3061 3062 smp_wmb(); /* make pte visible before pmd */ 3063 pmd_populate(mm, pmd, pgtable); 3064 } 3065 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 21+ messages in thread
* [syzbot ci] Re: mm: add huge pfnmap support for remap_pfn_range() 2025-09-23 13:31 ` Yin Tirui @ 2025-09-23 22:53 ` syzbot ci -1 siblings, 0 replies; 21+ messages in thread From: syzbot ci @ 2025-09-23 22:53 UTC (permalink / raw) To: abrestic, akpm, alex, anshuman.khandual, aou, apopple, ardb, baohua, baolin.wang, catalin.marinas, chenjun102, david, dev.jain, liam.howlett, linux-arm-kernel, linux-kernel, linux-mm, linux-riscv, lorenzo.stoakes, luxu.kernel, mhocko, npache, palmer, paul.walmsley, rppt, ryan.roberts, samuel.holland, surenb, vbabka, wangkefeng.wang, will, willy, yangyicong, yintirui, yongxuan.wang, ziy Cc: syzbot, syzkaller-bugs syzbot ci has tested the following series [v1] mm: add huge pfnmap support for remap_pfn_range() https://lore.kernel.org/all/20250923133104.926672-1-yintirui@huawei.com * [PATCH RFC 1/2] pgtable: add pte_clrhuge() implementation for arm64 and riscv * [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() and found the following issues: * BUG: non-zero pgtables_bytes on freeing mm: NUM * stack segment fault in pgtable_trans_huge_withdraw Full report is available here: https://ci.syzbot.org/series/633cbff7-ef54-4f3a-9133-71cc271396ee *** BUG: non-zero pgtables_bytes on freeing mm: NUM tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 07e27ad16399afcd693be20211b0dfae63e0615f arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/72b4b6cf-5400-40d6-94b6-1cfc0e85050d/config C repro: https://ci.syzbot.org/findings/3450ef75-3540-4c00-8b33-5625d4aa40ef/c_repro syz repro: https://ci.syzbot.org/findings/3450ef75-3540-4c00-8b33-5625d4aa40ef/syz_repro BUG: non-zero pgtables_bytes on freeing mm: 4096 *** stack segment fault in pgtable_trans_huge_withdraw tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 07e27ad16399afcd693be20211b0dfae63e0615f arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/72b4b6cf-5400-40d6-94b6-1cfc0e85050d/config C repro: https://ci.syzbot.org/findings/dcfb72b5-c263-48da-830a-7f51aaa927db/c_repro syz repro: https://ci.syzbot.org/findings/dcfb72b5-c263-48da-830a-7f51aaa927db/syz_repro Oops: stack segment: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 6000 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 5d 38 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 3b 38 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90002d5f300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea0000fb3dd0 RCX: ffff888107769cc0 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff888022b90843 R09: 1ffff11004572108 R10: dffffc0000000000 R11: ffffed1004572109 R12: ffff88803ecf7000 R13: dffffc0000000000 R14: ffff88803ecf7000 R15: 0000000000000008 FS: 0000555576e7a500(0000) GS:ffff8880b8612000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000107d74000 CR4: 00000000000006f0 Call Trace: <TASK> zap_deposited_table mm/huge_memory.c:2177 [inline] zap_huge_pmd+0xa25/0xf50 mm/huge_memory.c:2205 zap_pmd_range mm/memory.c:1798 [inline] zap_pud_range mm/memory.c:1847 [inline] zap_p4d_range mm/memory.c:1868 [inline] unmap_page_range+0x9fe/0x4370 mm/memory.c:1889 unmap_single_vma mm/memory.c:1932 [inline] unmap_vmas+0x399/0x580 mm/memory.c:1976 exit_mmap+0x248/0xb50 mm/mmap.c:1280 __mmput+0x118/0x430 kernel/fork.c:1129 copy_process+0x2910/0x3c00 kernel/fork.c:2454 kernel_clone+0x21e/0x840 kernel/fork.c:2605 __do_sys_clone kernel/fork.c:2748 [inline] __se_sys_clone kernel/fork.c:2732 [inline] __x64_sys_clone+0x18b/0x1e0 kernel/fork.c:2732 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f96b638ec29 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc07e618c8 EFLAGS: 00000206 ORIG_RAX: 0000000000000038 RAX: ffffffffffffffda RBX: 00007f96b65d5fa0 RCX: 00007f96b638ec29 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000002001000 RBP: 00007f96b6411e41 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000 R13: 00007f96b65d5fa0 R14: 00007f96b65d5fa0 R15: 0000000000000006 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 5d 38 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 3b 38 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90002d5f300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea0000fb3dd0 RCX: ffff888107769cc0 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff888022b90843 R09: 1ffff11004572108 R10: dffffc0000000000 R11: ffffed1004572109 R12: ffff88803ecf7000 R13: dffffc0000000000 R14: ffff88803ecf7000 R15: 0000000000000008 FS: 0000555576e7a500(0000) GS:ffff8880b8612000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000107d74000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: c3 ret 1: 10 48 89 adc %cl,-0x77(%rax) 4: d8 48 c1 fmuls -0x3f(%rax) 7: e8 03 42 80 3c call 0x3c80420f c: 28 00 sub %al,(%rax) e: 74 08 je 0x18 10: 48 89 df mov %rbx,%rdi 13: e8 5d 38 13 00 call 0x133875 18: 48 8b 03 mov (%rbx),%rax 1b: 48 89 04 24 mov %rax,(%rsp) 1f: 4c 8d 78 08 lea 0x8(%rax),%r15 23: 4c 89 fd mov %r15,%rbp 26: 48 c1 ed 03 shr $0x3,%rbp * 2a: 42 80 7c 2d 00 00 cmpb $0x0,0x0(%rbp,%r13,1) <-- trapping instruction 30: 74 08 je 0x3a 32: 4c 89 ff mov %r15,%rdi 35: e8 3b 38 13 00 call 0x133875 3a: 49 8b 07 mov (%r15),%rax 3d: 48 rex.W 3e: 8d .byte 0x8d 3f: 48 rex.W *** If these findings have caused you to resend the series or submit a separate fix, please add the following tag to your commit message: Tested-by: syzbot@syzkaller.appspotmail.com --- This report is generated by a bot. It may contain errors. syzbot ci engineers can be reached at syzkaller@googlegroups.com. ^ permalink raw reply [flat|nested] 21+ messages in thread
* [syzbot ci] Re: mm: add huge pfnmap support for remap_pfn_range() @ 2025-09-23 22:53 ` syzbot ci 0 siblings, 0 replies; 21+ messages in thread From: syzbot ci @ 2025-09-23 22:53 UTC (permalink / raw) To: abrestic, akpm, alex, anshuman.khandual, aou, apopple, ardb, baohua, baolin.wang, catalin.marinas, chenjun102, david, dev.jain, liam.howlett, linux-arm-kernel, linux-kernel, linux-mm, linux-riscv, lorenzo.stoakes, luxu.kernel, mhocko, npache, palmer, paul.walmsley, rppt, ryan.roberts, samuel.holland, surenb, vbabka, wangkefeng.wang, will, willy, yangyicong, yintirui, yongxuan.wang, ziy Cc: syzbot, syzkaller-bugs syzbot ci has tested the following series [v1] mm: add huge pfnmap support for remap_pfn_range() https://lore.kernel.org/all/20250923133104.926672-1-yintirui@huawei.com * [PATCH RFC 1/2] pgtable: add pte_clrhuge() implementation for arm64 and riscv * [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() and found the following issues: * BUG: non-zero pgtables_bytes on freeing mm: NUM * stack segment fault in pgtable_trans_huge_withdraw Full report is available here: https://ci.syzbot.org/series/633cbff7-ef54-4f3a-9133-71cc271396ee *** BUG: non-zero pgtables_bytes on freeing mm: NUM tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 07e27ad16399afcd693be20211b0dfae63e0615f arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/72b4b6cf-5400-40d6-94b6-1cfc0e85050d/config C repro: https://ci.syzbot.org/findings/3450ef75-3540-4c00-8b33-5625d4aa40ef/c_repro syz repro: https://ci.syzbot.org/findings/3450ef75-3540-4c00-8b33-5625d4aa40ef/syz_repro BUG: non-zero pgtables_bytes on freeing mm: 4096 *** stack segment fault in pgtable_trans_huge_withdraw tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 07e27ad16399afcd693be20211b0dfae63e0615f arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/72b4b6cf-5400-40d6-94b6-1cfc0e85050d/config C repro: https://ci.syzbot.org/findings/dcfb72b5-c263-48da-830a-7f51aaa927db/c_repro syz repro: https://ci.syzbot.org/findings/dcfb72b5-c263-48da-830a-7f51aaa927db/syz_repro Oops: stack segment: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 6000 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 5d 38 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 3b 38 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90002d5f300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea0000fb3dd0 RCX: ffff888107769cc0 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff888022b90843 R09: 1ffff11004572108 R10: dffffc0000000000 R11: ffffed1004572109 R12: ffff88803ecf7000 R13: dffffc0000000000 R14: ffff88803ecf7000 R15: 0000000000000008 FS: 0000555576e7a500(0000) GS:ffff8880b8612000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000107d74000 CR4: 00000000000006f0 Call Trace: <TASK> zap_deposited_table mm/huge_memory.c:2177 [inline] zap_huge_pmd+0xa25/0xf50 mm/huge_memory.c:2205 zap_pmd_range mm/memory.c:1798 [inline] zap_pud_range mm/memory.c:1847 [inline] zap_p4d_range mm/memory.c:1868 [inline] unmap_page_range+0x9fe/0x4370 mm/memory.c:1889 unmap_single_vma mm/memory.c:1932 [inline] unmap_vmas+0x399/0x580 mm/memory.c:1976 exit_mmap+0x248/0xb50 mm/mmap.c:1280 __mmput+0x118/0x430 kernel/fork.c:1129 copy_process+0x2910/0x3c00 kernel/fork.c:2454 kernel_clone+0x21e/0x840 kernel/fork.c:2605 __do_sys_clone kernel/fork.c:2748 [inline] __se_sys_clone kernel/fork.c:2732 [inline] __x64_sys_clone+0x18b/0x1e0 kernel/fork.c:2732 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f96b638ec29 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc07e618c8 EFLAGS: 00000206 ORIG_RAX: 0000000000000038 RAX: ffffffffffffffda RBX: 00007f96b65d5fa0 RCX: 00007f96b638ec29 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000002001000 RBP: 00007f96b6411e41 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000 R13: 00007f96b65d5fa0 R14: 00007f96b65d5fa0 R15: 0000000000000006 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 5d 38 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 3b 38 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90002d5f300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea0000fb3dd0 RCX: ffff888107769cc0 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff888022b90843 R09: 1ffff11004572108 R10: dffffc0000000000 R11: ffffed1004572109 R12: ffff88803ecf7000 R13: dffffc0000000000 R14: ffff88803ecf7000 R15: 0000000000000008 FS: 0000555576e7a500(0000) GS:ffff8880b8612000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000107d74000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: c3 ret 1: 10 48 89 adc %cl,-0x77(%rax) 4: d8 48 c1 fmuls -0x3f(%rax) 7: e8 03 42 80 3c call 0x3c80420f c: 28 00 sub %al,(%rax) e: 74 08 je 0x18 10: 48 89 df mov %rbx,%rdi 13: e8 5d 38 13 00 call 0x133875 18: 48 8b 03 mov (%rbx),%rax 1b: 48 89 04 24 mov %rax,(%rsp) 1f: 4c 8d 78 08 lea 0x8(%rax),%r15 23: 4c 89 fd mov %r15,%rbp 26: 48 c1 ed 03 shr $0x3,%rbp * 2a: 42 80 7c 2d 00 00 cmpb $0x0,0x0(%rbp,%r13,1) <-- trapping instruction 30: 74 08 je 0x3a 32: 4c 89 ff mov %r15,%rdi 35: e8 3b 38 13 00 call 0x133875 3a: 49 8b 07 mov (%r15),%rax 3d: 48 rex.W 3e: 8d .byte 0x8d 3f: 48 rex.W *** If these findings have caused you to resend the series or submit a separate fix, please add the following tag to your commit message: Tested-by: syzbot@syzkaller.appspotmail.com --- This report is generated by a bot. It may contain errors. syzbot ci engineers can be reached at syzkaller@googlegroups.com. _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC v2 0/2] mm: add huge pfnmap support for remap_pfn_range()
@ 2025-10-16 11:27 Yin Tirui
2025-10-16 16:23 ` syzbot ci
0 siblings, 1 reply; 21+ messages in thread
From: Yin Tirui @ 2025-10-16 11:27 UTC (permalink / raw)
To: akpm, david, lorenzo.stoakes, Liam.Howlett, vbabka, rppt, surenb,
mhocko, ziy, baolin.wang, npache, ryan.roberts, dev.jain, baohua,
catalin.marinas, will, paul.walmsley, palmer, aou, alex,
anshuman.khandual, yangyicong, ardb, willy, apopple,
samuel.holland, luxu.kernel, abrestic, yongxuan.wang, linux-mm,
linux-kernel, linux-arm-kernel, linux-riscv
Cc: wangkefeng.wang, chenjun102, yintirui
v2:
- remove "nohugepfnmap" boot option and "pfnmap_max_page_shift" variable.
- zap_deposited_table for non-special pmd.
- move set_pmd_at() inside pmd_lock.
- prevent PMD mapping creation when pgtable allocation fails.
- defer the refactor of pte_clrhuge() to a separate patch series. For now,
add a TODO to track this.
v1: https://lore.kernel.org/linux-mm/20250923133104.926672-1-yintirui@huawei.com/
Overview
========
This patch series adds huge page support for remap_pfn_range(),
automatically creating huge mappings when prerequisites are satisfied
(size, alignment, architecture support, etc.) and falling back to
normal page mappings otherwise.
This work builds on Peter Xu's previous efforts on huge pfnmap
support [0].
TODO
====
- Add PUD-level huge page support. Currently, only PMD-level huge
pages are supported.
- Consider the logic related to vmap_page_range and extract
reusable common code.
- Refactor pte_clrhuge() and related functions.
Tests Done
==========
- Cross-build tests.
- Performance tests with custom device driver implementing mmap()
with remap_pfn_range():
- lat_mem_rd benchmark modified to use mmap(device_fd) instead of
malloc() shows around 40% improvement in memory access latency with
huge page support compared to normal page mappings.
numactl -C 0 lat_mem_rd -t 4096M (stride=64)
Memory Size (MB) Without Huge Mapping With Huge Mapping Improvement
---------------- ----------------- -------------- -----------
64.00 148.858 ns 100.780 ns 32.3%
128.00 164.745 ns 103.537 ns 37.2%
256.00 169.907 ns 103.179 ns 39.3%
512.00 171.285 ns 103.072 ns 39.8%
1024.00 173.054 ns 103.055 ns 40.4%
2048.00 172.820 ns 103.091 ns 40.3%
4096.00 172.877 ns 103.115 ns 40.4%
- Custom memory copy operations on mmap(device_fd) show around 18% performance
improvement with huge page support compared to normal page mappings.
numactl -C 0 memcpy_test (memory copy performance test)
Memory Size (MB) Without Huge Mapping With Huge Mapping Improvement
---------------- ----------------- -------------- -----------
1024.00 95.76 ms 77.91 ms 18.6%
2048.00 190.87 ms 155.64 ms 18.5%
4096.00 380.84 ms 311.45 ms 18.2%
[0] https://lore.kernel.org/all/20240826204353.2228736-2-peterx@redhat.com/T/#u
Yin Tirui (2):
pgtable: add pte_clrhuge() implementation for arm64 and riscv
mm: add PMD-level huge page support for remap_pfn_range()
arch/arm64/include/asm/pgtable.h | 8 +++++++
arch/riscv/include/asm/pgtable.h | 5 ++++
include/linux/pgtable.h | 6 ++++-
mm/huge_memory.c | 26 +++++++++++++++------
mm/memory.c | 40 ++++++++++++++++++++++++++++++++
5 files changed, 77 insertions(+), 8 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 21+ messages in thread* [syzbot ci] Re: mm: add huge pfnmap support for remap_pfn_range() 2025-10-16 11:27 [PATCH RFC v2 0/2] " Yin Tirui @ 2025-10-16 16:23 ` syzbot ci 0 siblings, 0 replies; 21+ messages in thread From: syzbot ci @ 2025-10-16 16:23 UTC (permalink / raw) To: abrestic, akpm, alex, anshuman.khandual, aou, apopple, ardb, baohua, baolin.wang, catalin.marinas, chenjun102, david, dev.jain, liam.howlett, linux-arm-kernel, linux-kernel, linux-mm, linux-riscv, lorenzo.stoakes, luxu.kernel, mhocko, npache, palmer, paul.walmsley, rppt, ryan.roberts, samuel.holland, surenb, vbabka, wangkefeng.wang, will, willy, yangyicong, yintirui, yongxuan.wang, ziy Cc: syzbot, syzkaller-bugs syzbot ci has tested the following series [v2] mm: add huge pfnmap support for remap_pfn_range() https://lore.kernel.org/all/20251016112704.179280-1-yintirui@huawei.com * [PATCH RFC 1/2] pgtable: add pte_clrhuge() implementation for arm64 and riscv * [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() and found the following issue: stack segment fault in pgtable_trans_huge_withdraw Full report is available here: https://ci.syzbot.org/series/d04c2914-0d99-4132-89d4-899e22abf904 *** stack segment fault in pgtable_trans_huge_withdraw tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 3a8660878839faadb4f1a6dd72c3179c1df56787 arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/9d7864e5-ad3a-4c0d-b21d-86cfc476792e/config C repro: https://ci.syzbot.org/findings/b9fca361-413d-4db1-b8b2-1849cd2c50dd/c_repro syz repro: https://ci.syzbot.org/findings/b9fca361-413d-4db1-b8b2-1849cd2c50dd/syz_repro Oops: stack segment: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 5968 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 9d e9 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 7b e9 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90003717300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea00044848d0 RCX: ffff88816c890000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff88816db66a23 R09: 1ffff1102db6cd44 R10: dffffc0000000000 R11: ffffed102db6cd45 R12: ffff888112123000 R13: dffffc0000000000 R14: ffff888112123000 R15: 0000000000000008 FS: 000055556cb5f500(0000) GS:ffff88818e70c000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001102a4000 CR4: 00000000000006f0 Call Trace: <TASK> zap_deposited_table mm/huge_memory.c:2169 [inline] zap_huge_pmd+0xa25/0xf50 mm/huge_memory.c:2197 zap_pmd_range mm/memory.c:1926 [inline] zap_pud_range mm/memory.c:1975 [inline] zap_p4d_range mm/memory.c:1996 [inline] unmap_page_range+0x9fe/0x4370 mm/memory.c:2017 unmap_single_vma mm/memory.c:2060 [inline] unmap_vmas+0x399/0x580 mm/memory.c:2104 exit_mmap+0x240/0xb40 mm/mmap.c:1280 __mmput+0x118/0x430 kernel/fork.c:1133 copy_process+0x2910/0x3c00 kernel/fork.c:2460 kernel_clone+0x21e/0x840 kernel/fork.c:2609 __do_sys_clone kernel/fork.c:2750 [inline] __se_sys_clone kernel/fork.c:2734 [inline] __x64_sys_clone+0x18b/0x1e0 kernel/fork.c:2734 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f946958eec9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc41c94258 EFLAGS: 00000206 ORIG_RAX: 0000000000000038 RAX: ffffffffffffffda RBX: 00007f94697e5fa0 RCX: 00007f946958eec9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000002001000 RBP: 00007f9469611f91 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000 R13: 00007f94697e5fa0 R14: 00007f94697e5fa0 R15: 0000000000000006 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 9d e9 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 7b e9 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90003717300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea00044848d0 RCX: ffff88816c890000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff88816db66a23 R09: 1ffff1102db6cd44 R10: dffffc0000000000 R11: ffffed102db6cd45 R12: ffff888112123000 R13: dffffc0000000000 R14: ffff888112123000 R15: 0000000000000008 FS: 000055556cb5f500(0000) GS:ffff88818e70c000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001102a4000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: c3 ret 1: 10 48 89 adc %cl,-0x77(%rax) 4: d8 48 c1 fmuls -0x3f(%rax) 7: e8 03 42 80 3c call 0x3c80420f c: 28 00 sub %al,(%rax) e: 74 08 je 0x18 10: 48 89 df mov %rbx,%rdi 13: e8 9d e9 13 00 call 0x13e9b5 18: 48 8b 03 mov (%rbx),%rax 1b: 48 89 04 24 mov %rax,(%rsp) 1f: 4c 8d 78 08 lea 0x8(%rax),%r15 23: 4c 89 fd mov %r15,%rbp 26: 48 c1 ed 03 shr $0x3,%rbp * 2a: 42 80 7c 2d 00 00 cmpb $0x0,0x0(%rbp,%r13,1) <-- trapping instruction 30: 74 08 je 0x3a 32: 4c 89 ff mov %r15,%rdi 35: e8 7b e9 13 00 call 0x13e9b5 3a: 49 8b 07 mov (%r15),%rax 3d: 48 rex.W 3e: 8d .byte 0x8d 3f: 48 rex.W *** If these findings have caused you to resend the series or submit a separate fix, please add the following tag to your commit message: Tested-by: syzbot@syzkaller.appspotmail.com --- This report is generated by a bot. It may contain errors. syzbot ci engineers can be reached at syzkaller@googlegroups.com. ^ permalink raw reply [flat|nested] 21+ messages in thread
* [syzbot ci] Re: mm: add huge pfnmap support for remap_pfn_range() @ 2025-10-16 16:23 ` syzbot ci 0 siblings, 0 replies; 21+ messages in thread From: syzbot ci @ 2025-10-16 16:23 UTC (permalink / raw) To: abrestic, akpm, alex, anshuman.khandual, aou, apopple, ardb, baohua, baolin.wang, catalin.marinas, chenjun102, david, dev.jain, liam.howlett, linux-arm-kernel, linux-kernel, linux-mm, linux-riscv, lorenzo.stoakes, luxu.kernel, mhocko, npache, palmer, paul.walmsley, rppt, ryan.roberts, samuel.holland, surenb, vbabka, wangkefeng.wang, will, willy, yangyicong, yintirui, yongxuan.wang, ziy Cc: syzbot, syzkaller-bugs syzbot ci has tested the following series [v2] mm: add huge pfnmap support for remap_pfn_range() https://lore.kernel.org/all/20251016112704.179280-1-yintirui@huawei.com * [PATCH RFC 1/2] pgtable: add pte_clrhuge() implementation for arm64 and riscv * [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() and found the following issue: stack segment fault in pgtable_trans_huge_withdraw Full report is available here: https://ci.syzbot.org/series/d04c2914-0d99-4132-89d4-899e22abf904 *** stack segment fault in pgtable_trans_huge_withdraw tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 3a8660878839faadb4f1a6dd72c3179c1df56787 arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/9d7864e5-ad3a-4c0d-b21d-86cfc476792e/config C repro: https://ci.syzbot.org/findings/b9fca361-413d-4db1-b8b2-1849cd2c50dd/c_repro syz repro: https://ci.syzbot.org/findings/b9fca361-413d-4db1-b8b2-1849cd2c50dd/syz_repro Oops: stack segment: 0000 [#1] SMP KASAN PTI CPU: 0 UID: 0 PID: 5968 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 9d e9 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 7b e9 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90003717300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea00044848d0 RCX: ffff88816c890000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff88816db66a23 R09: 1ffff1102db6cd44 R10: dffffc0000000000 R11: ffffed102db6cd45 R12: ffff888112123000 R13: dffffc0000000000 R14: ffff888112123000 R15: 0000000000000008 FS: 000055556cb5f500(0000) GS:ffff88818e70c000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001102a4000 CR4: 00000000000006f0 Call Trace: <TASK> zap_deposited_table mm/huge_memory.c:2169 [inline] zap_huge_pmd+0xa25/0xf50 mm/huge_memory.c:2197 zap_pmd_range mm/memory.c:1926 [inline] zap_pud_range mm/memory.c:1975 [inline] zap_p4d_range mm/memory.c:1996 [inline] unmap_page_range+0x9fe/0x4370 mm/memory.c:2017 unmap_single_vma mm/memory.c:2060 [inline] unmap_vmas+0x399/0x580 mm/memory.c:2104 exit_mmap+0x240/0xb40 mm/mmap.c:1280 __mmput+0x118/0x430 kernel/fork.c:1133 copy_process+0x2910/0x3c00 kernel/fork.c:2460 kernel_clone+0x21e/0x840 kernel/fork.c:2609 __do_sys_clone kernel/fork.c:2750 [inline] __se_sys_clone kernel/fork.c:2734 [inline] __x64_sys_clone+0x18b/0x1e0 kernel/fork.c:2734 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f946958eec9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffc41c94258 EFLAGS: 00000206 ORIG_RAX: 0000000000000038 RAX: ffffffffffffffda RBX: 00007f94697e5fa0 RCX: 00007f946958eec9 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000002001000 RBP: 00007f9469611f91 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000 R13: 00007f94697e5fa0 R14: 00007f94697e5fa0 R15: 0000000000000006 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:pgtable_trans_huge_withdraw+0x115/0x310 mm/pgtable-generic.c:188 Code: c3 10 48 89 d8 48 c1 e8 03 42 80 3c 28 00 74 08 48 89 df e8 9d e9 13 00 48 8b 03 48 89 04 24 4c 8d 78 08 4c 89 fd 48 c1 ed 03 <42> 80 7c 2d 00 00 74 08 4c 89 ff e8 7b e9 13 00 49 8b 07 48 8d 48 RSP: 0018:ffffc90003717300 EFLAGS: 00010202 RAX: 0000000000000000 RBX: ffffea00044848d0 RCX: ffff88816c890000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff88816db66a23 R09: 1ffff1102db6cd44 R10: dffffc0000000000 R11: ffffed102db6cd45 R12: ffff888112123000 R13: dffffc0000000000 R14: ffff888112123000 R15: 0000000000000008 FS: 000055556cb5f500(0000) GS:ffff88818e70c000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001102a4000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: c3 ret 1: 10 48 89 adc %cl,-0x77(%rax) 4: d8 48 c1 fmuls -0x3f(%rax) 7: e8 03 42 80 3c call 0x3c80420f c: 28 00 sub %al,(%rax) e: 74 08 je 0x18 10: 48 89 df mov %rbx,%rdi 13: e8 9d e9 13 00 call 0x13e9b5 18: 48 8b 03 mov (%rbx),%rax 1b: 48 89 04 24 mov %rax,(%rsp) 1f: 4c 8d 78 08 lea 0x8(%rax),%r15 23: 4c 89 fd mov %r15,%rbp 26: 48 c1 ed 03 shr $0x3,%rbp * 2a: 42 80 7c 2d 00 00 cmpb $0x0,0x0(%rbp,%r13,1) <-- trapping instruction 30: 74 08 je 0x3a 32: 4c 89 ff mov %r15,%rdi 35: e8 7b e9 13 00 call 0x13e9b5 3a: 49 8b 07 mov (%r15),%rax 3d: 48 rex.W 3e: 8d .byte 0x8d 3f: 48 rex.W *** If these findings have caused you to resend the series or submit a separate fix, please add the following tag to your commit message: Tested-by: syzbot@syzkaller.appspotmail.com --- This report is generated by a bot. It may contain errors. syzbot ci engineers can be reached at syzkaller@googlegroups.com. _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2025-10-16 16:24 UTC | newest] Thread overview: 21+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-23 13:31 [PATCH RFC 0/2] mm: add huge pfnmap support for remap_pfn_range() Yin Tirui 2025-09-23 13:31 ` Yin Tirui 2025-09-23 13:31 ` [PATCH RFC 1/2] pgtable: add pte_clrhuge() implementation for arm64 and riscv Yin Tirui 2025-09-23 13:31 ` Yin Tirui 2025-09-23 13:31 ` [PATCH RFC 2/2] mm: add PMD-level huge page support for remap_pfn_range() Yin Tirui 2025-09-23 13:31 ` Yin Tirui 2025-09-23 22:39 ` Matthew Wilcox 2025-09-23 22:39 ` Matthew Wilcox 2025-09-25 2:17 ` Yin Tirui 2025-09-25 2:17 ` Yin Tirui 2025-09-24 9:50 ` David Hildenbrand 2025-09-24 9:50 ` David Hildenbrand 2025-09-25 1:43 ` Yin Tirui 2025-09-25 1:43 ` Yin Tirui 2025-09-25 9:38 ` David Hildenbrand 2025-09-25 9:38 ` David Hildenbrand 2025-09-25 3:14 ` kernel test robot 2025-09-23 22:53 ` [syzbot ci] Re: mm: add huge pfnmap " syzbot ci 2025-09-23 22:53 ` syzbot ci -- strict thread matches above, loose matches on Subject: below -- 2025-10-16 11:27 [PATCH RFC v2 0/2] " Yin Tirui 2025-10-16 16:23 ` [syzbot ci] " syzbot ci 2025-10-16 16:23 ` syzbot ci
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.