* [PATCH 0/4] hugetlb: speed up linear address scanning @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz At unmap, fork and remap time hugetlb address ranges are linearly scanned. We can optimize these scans if the ranges are sparsely populated. Also, enable page table "Lazy copy" for hugetlb at fork. NOTE: Architectures not defining CONFIG_ARCH_WANT_GENERAL_HUGETLB need to add an arch specific version hugetlb_mask_last_page() to take advantage of sparse address scanning improvements. Baolin Wang added the routine for arm64. Other architectures which could be optimized are: ia64, mips, parisc, powerpc, s390, sh and sparc. Baolin Wang (1): arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page Mike Kravetz (3): hugetlb: skip to end of PT page mapping when pte not present hugetlb: do not update address in huge_pmd_unshare hugetlb: Lazy page table copies in fork() arch/arm64/mm/hugetlbpage.c | 20 +++++++ include/linux/hugetlb.h | 5 +- mm/hugetlb.c | 109 +++++++++++++++++++++++++----------- mm/memory.c | 2 +- mm/rmap.c | 4 +- 5 files changed, 103 insertions(+), 37 deletions(-) -- 2.35.3 ^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH 0/4] hugetlb: speed up linear address scanning @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz At unmap, fork and remap time hugetlb address ranges are linearly scanned. We can optimize these scans if the ranges are sparsely populated. Also, enable page table "Lazy copy" for hugetlb at fork. NOTE: Architectures not defining CONFIG_ARCH_WANT_GENERAL_HUGETLB need to add an arch specific version hugetlb_mask_last_page() to take advantage of sparse address scanning improvements. Baolin Wang added the routine for arm64. Other architectures which could be optimized are: ia64, mips, parisc, powerpc, s390, sh and sparc. Baolin Wang (1): arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page Mike Kravetz (3): hugetlb: skip to end of PT page mapping when pte not present hugetlb: do not update address in huge_pmd_unshare hugetlb: Lazy page table copies in fork() arch/arm64/mm/hugetlbpage.c | 20 +++++++ include/linux/hugetlb.h | 5 +- mm/hugetlb.c | 109 +++++++++++++++++++++++++----------- mm/memory.c | 2 +- mm/rmap.c | 4 +- 5 files changed, 103 insertions(+), 37 deletions(-) -- 2.35.3 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH 0/4] hugetlb: speed up linear address scanning @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Mina Almasry, James Houghton, will, Anshuman Khandual, catalin.marinas, Paul Walmsley, Peter Xu, Michal Hocko, Aneesh Kumar K . V, Baolin Wang, Muchun Song, Andrew Morton, Christian Borntraeger, Naoya Horiguchi, Mike Kravetz At unmap, fork and remap time hugetlb address ranges are linearly scanned. We can optimize these scans if the ranges are sparsely populated. Also, enable page table "Lazy copy" for hugetlb at fork. NOTE: Architectures not defining CONFIG_ARCH_WANT_GENERAL_HUGETLB need to add an arch specific version hugetlb_mask_last_page() to take advantage of sparse address scanning improvements. Baolin Wang added the routine for arm64. Other architectures which could be optimized are: ia64, mips, parisc, powerpc, s390, sh and sparc. Baolin Wang (1): arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page Mike Kravetz (3): hugetlb: skip to end of PT page mapping when pte not present hugetlb: do not update address in huge_pmd_unshare hugetlb: Lazy page table copies in fork() arch/arm64/mm/hugetlbpage.c | 20 +++++++ include/linux/hugetlb.h | 5 +- mm/hugetlb.c | 109 +++++++++++++++++++++++++----------- mm/memory.c | 2 +- mm/rmap.c | 4 +- 5 files changed, 103 insertions(+), 37 deletions(-) -- 2.35.3 ^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH 0/4] hugetlb: speed up linear address scanning @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz At unmap, fork and remap time hugetlb address ranges are linearly scanned. We can optimize these scans if the ranges are sparsely populated. Also, enable page table "Lazy copy" for hugetlb at fork. NOTE: Architectures not defining CONFIG_ARCH_WANT_GENERAL_HUGETLB need to add an arch specific version hugetlb_mask_last_page() to take advantage of sparse address scanning improvements. Baolin Wang added the routine for arm64. Other architectures which could be optimized are: ia64, mips, parisc, powerpc, s390, sh and sparc. Baolin Wang (1): arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page Mike Kravetz (3): hugetlb: skip to end of PT page mapping when pte not present hugetlb: do not update address in huge_pmd_unshare hugetlb: Lazy page table copies in fork() arch/arm64/mm/hugetlbpage.c | 20 +++++++ include/linux/hugetlb.h | 5 +- mm/hugetlb.c | 109 +++++++++++++++++++++++++----------- mm/memory.c | 2 +- mm/rmap.c | 4 +- 5 files changed, 103 insertions(+), 37 deletions(-) -- 2.35.3 ^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-16 21:05 ` Mike Kravetz -1 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz HugeTLB address ranges are linearly scanned during fork, unmap and remap operations. If a non-present entry is encountered, the code currently continues to the next huge page aligned address. However, a non-present entry implies that the page table page for that entry is not present. Therefore, the linear scan can skip to the end of range mapped by the page table page. This can speed operations on large sparsely populated hugetlb mappings. Create a new routine hugetlb_mask_last_page() that will return an address mask. When the mask is ORed with an address, the result will be the address of the last huge page mapped by the associated page table page. Use this mask to update addresses in routines which linearly scan hugetlb address ranges when a non-present pte is encountered. hugetlb_mask_last_page is related to the implementation of huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset returns NULL. This patch only provides a complete hugetlb_mask_last_page implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. Architectures which provide their own versions of huge_pte_offset can also provide their own version of hugetlb_mask_last_page. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 1 + mm/hugetlb.c | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 642a39016f9a..e37465e830fe 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -197,6 +197,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz); pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); +unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long *addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 259b9c41892f..7c4a82848603 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4740,6 +4740,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, unsigned long npages = pages_per_huge_page(h); struct address_space *mapping = src_vma->vm_file->f_mapping; struct mmu_notifier_range range; + unsigned long last_addr_mask; int ret = 0; if (cow) { @@ -4759,11 +4760,14 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, i_mmap_lock_read(mapping); } + last_addr_mask = hugetlb_mask_last_page(h); for (addr = src_vma->vm_start; addr < src_vma->vm_end; addr += sz) { spinlock_t *src_ptl, *dst_ptl; src_pte = huge_pte_offset(src, addr, sz); - if (!src_pte) + if (!src_pte) { + addr |= last_addr_mask; continue; + } dst_pte = huge_pte_alloc(dst, dst_vma, addr, sz); if (!dst_pte) { ret = -ENOMEM; @@ -4780,8 +4784,10 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, * after taking the lock below. */ dst_entry = huge_ptep_get(dst_pte); - if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) + if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) { + addr |= last_addr_mask; continue; + } dst_ptl = huge_pte_lock(h, dst, dst_pte); src_ptl = huge_pte_lockptr(h, src, src_pte); @@ -4942,6 +4948,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, unsigned long sz = huge_page_size(h); struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; + unsigned long last_addr_mask; unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; @@ -4957,12 +4964,16 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); /* Prevent race with file truncation */ i_mmap_lock_write(mapping); for (; old_addr < old_end; old_addr += sz, new_addr += sz) { src_pte = huge_pte_offset(mm, old_addr, sz); - if (!src_pte) + if (!src_pte) { + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; + } if (huge_pte_none(huge_ptep_get(src_pte))) continue; @@ -5007,6 +5018,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); struct mmu_notifier_range range; + unsigned long last_addr_mask; bool force_flush = false; WARN_ON(!is_vm_hugetlb_page(vma)); @@ -5027,11 +5039,14 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct end); adjust_range_if_pmd_sharing_possible(vma, &range.start, &range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); address = start; for (; address < end; address += sz) { ptep = huge_pte_offset(mm, address, sz); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { @@ -6305,6 +6320,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, unsigned long pages = 0, psize = huge_page_size(h); bool shared_pmd = false; struct mmu_notifier_range range; + unsigned long last_addr_mask; bool uffd_wp = cp_flags & MM_CP_UFFD_WP; bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE; @@ -6321,12 +6337,15 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); i_mmap_lock_write(vma->vm_file->f_mapping); for (; address < end; address += psize) { spinlock_t *ptl; ptep = huge_pte_offset(mm, address, psize); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { /* @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return (pte_t *)pmd; } +/* + * Return a mask that can be used to update an address to the last huge + * page in a page table page mapping size. Used to skip non-present + * page table entries when linearly scanning address ranges. Architectures + * with unique huge page to page table relationships can define their own + * version of this routine. + */ +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case P4D_SIZE: + return PGDIR_SIZE - P4D_SIZE; + case PUD_SIZE: + return P4D_SIZE - PUD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + default: + break; /* Should never happen */ + } + + return ~(0UL); +} + +#else + +/* See description above. Architectures can provide their own version. */ +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + return ~(0UL); +} + #endif /* CONFIG_ARCH_WANT_GENERAL_HUGETLB */ /* -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz HugeTLB address ranges are linearly scanned during fork, unmap and remap operations. If a non-present entry is encountered, the code currently continues to the next huge page aligned address. However, a non-present entry implies that the page table page for that entry is not present. Therefore, the linear scan can skip to the end of range mapped by the page table page. This can speed operations on large sparsely populated hugetlb mappings. Create a new routine hugetlb_mask_last_page() that will return an address mask. When the mask is ORed with an address, the result will be the address of the last huge page mapped by the associated page table page. Use this mask to update addresses in routines which linearly scan hugetlb address ranges when a non-present pte is encountered. hugetlb_mask_last_page is related to the implementation of huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset returns NULL. This patch only provides a complete hugetlb_mask_last_page implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. Architectures which provide their own versions of huge_pte_offset can also provide their own version of hugetlb_mask_last_page. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 1 + mm/hugetlb.c | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 642a39016f9a..e37465e830fe 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -197,6 +197,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz); pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); +unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long *addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 259b9c41892f..7c4a82848603 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4740,6 +4740,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, unsigned long npages = pages_per_huge_page(h); struct address_space *mapping = src_vma->vm_file->f_mapping; struct mmu_notifier_range range; + unsigned long last_addr_mask; int ret = 0; if (cow) { @@ -4759,11 +4760,14 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, i_mmap_lock_read(mapping); } + last_addr_mask = hugetlb_mask_last_page(h); for (addr = src_vma->vm_start; addr < src_vma->vm_end; addr += sz) { spinlock_t *src_ptl, *dst_ptl; src_pte = huge_pte_offset(src, addr, sz); - if (!src_pte) + if (!src_pte) { + addr |= last_addr_mask; continue; + } dst_pte = huge_pte_alloc(dst, dst_vma, addr, sz); if (!dst_pte) { ret = -ENOMEM; @@ -4780,8 +4784,10 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, * after taking the lock below. */ dst_entry = huge_ptep_get(dst_pte); - if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) + if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) { + addr |= last_addr_mask; continue; + } dst_ptl = huge_pte_lock(h, dst, dst_pte); src_ptl = huge_pte_lockptr(h, src, src_pte); @@ -4942,6 +4948,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, unsigned long sz = huge_page_size(h); struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; + unsigned long last_addr_mask; unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; @@ -4957,12 +4964,16 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); /* Prevent race with file truncation */ i_mmap_lock_write(mapping); for (; old_addr < old_end; old_addr += sz, new_addr += sz) { src_pte = huge_pte_offset(mm, old_addr, sz); - if (!src_pte) + if (!src_pte) { + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; + } if (huge_pte_none(huge_ptep_get(src_pte))) continue; @@ -5007,6 +5018,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); struct mmu_notifier_range range; + unsigned long last_addr_mask; bool force_flush = false; WARN_ON(!is_vm_hugetlb_page(vma)); @@ -5027,11 +5039,14 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct end); adjust_range_if_pmd_sharing_possible(vma, &range.start, &range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); address = start; for (; address < end; address += sz) { ptep = huge_pte_offset(mm, address, sz); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { @@ -6305,6 +6320,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, unsigned long pages = 0, psize = huge_page_size(h); bool shared_pmd = false; struct mmu_notifier_range range; + unsigned long last_addr_mask; bool uffd_wp = cp_flags & MM_CP_UFFD_WP; bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE; @@ -6321,12 +6337,15 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); i_mmap_lock_write(vma->vm_file->f_mapping); for (; address < end; address += psize) { spinlock_t *ptl; ptep = huge_pte_offset(mm, address, psize); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { /* @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return (pte_t *)pmd; } +/* + * Return a mask that can be used to update an address to the last huge + * page in a page table page mapping size. Used to skip non-present + * page table entries when linearly scanning address ranges. Architectures + * with unique huge page to page table relationships can define their own + * version of this routine. + */ +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case P4D_SIZE: + return PGDIR_SIZE - P4D_SIZE; + case PUD_SIZE: + return P4D_SIZE - PUD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + default: + break; /* Should never happen */ + } + + return ~(0UL); +} + +#else + +/* See description above. Architectures can provide their own version. */ +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + return ~(0UL); +} + #endif /* CONFIG_ARCH_WANT_GENERAL_HUGETLB */ /* -- 2.35.3 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Mina Almasry, James Houghton, will, Anshuman Khandual, catalin.marinas, Paul Walmsley, Peter Xu, Michal Hocko, Aneesh Kumar K . V, Baolin Wang, Muchun Song, Andrew Morton, Christian Borntraeger, Naoya Horiguchi, Mike Kravetz HugeTLB address ranges are linearly scanned during fork, unmap and remap operations. If a non-present entry is encountered, the code currently continues to the next huge page aligned address. However, a non-present entry implies that the page table page for that entry is not present. Therefore, the linear scan can skip to the end of range mapped by the page table page. This can speed operations on large sparsely populated hugetlb mappings. Create a new routine hugetlb_mask_last_page() that will return an address mask. When the mask is ORed with an address, the result will be the address of the last huge page mapped by the associated page table page. Use this mask to update addresses in routines which linearly scan hugetlb address ranges when a non-present pte is encountered. hugetlb_mask_last_page is related to the implementation of huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset returns NULL. This patch only provides a complete hugetlb_mask_last_page implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. Architectures which provide their own versions of huge_pte_offset can also provide their own version of hugetlb_mask_last_page. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 1 + mm/hugetlb.c | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 642a39016f9a..e37465e830fe 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -197,6 +197,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz); pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); +unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long *addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 259b9c41892f..7c4a82848603 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4740,6 +4740,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, unsigned long npages = pages_per_huge_page(h); struct address_space *mapping = src_vma->vm_file->f_mapping; struct mmu_notifier_range range; + unsigned long last_addr_mask; int ret = 0; if (cow) { @@ -4759,11 +4760,14 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, i_mmap_lock_read(mapping); } + last_addr_mask = hugetlb_mask_last_page(h); for (addr = src_vma->vm_start; addr < src_vma->vm_end; addr += sz) { spinlock_t *src_ptl, *dst_ptl; src_pte = huge_pte_offset(src, addr, sz); - if (!src_pte) + if (!src_pte) { + addr |= last_addr_mask; continue; + } dst_pte = huge_pte_alloc(dst, dst_vma, addr, sz); if (!dst_pte) { ret = -ENOMEM; @@ -4780,8 +4784,10 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, * after taking the lock below. */ dst_entry = huge_ptep_get(dst_pte); - if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) + if ((dst_pte == src_pte) || !huge_pte_none(dst_entry)) { + addr |= last_addr_mask; continue; + } dst_ptl = huge_pte_lock(h, dst, dst_pte); src_ptl = huge_pte_lockptr(h, src, src_pte); @@ -4942,6 +4948,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, unsigned long sz = huge_page_size(h); struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; + unsigned long last_addr_mask; unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; @@ -4957,12 +4964,16 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); /* Prevent race with file truncation */ i_mmap_lock_write(mapping); for (; old_addr < old_end; old_addr += sz, new_addr += sz) { src_pte = huge_pte_offset(mm, old_addr, sz); - if (!src_pte) + if (!src_pte) { + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; + } if (huge_pte_none(huge_ptep_get(src_pte))) continue; @@ -5007,6 +5018,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); struct mmu_notifier_range range; + unsigned long last_addr_mask; bool force_flush = false; WARN_ON(!is_vm_hugetlb_page(vma)); @@ -5027,11 +5039,14 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct end); adjust_range_if_pmd_sharing_possible(vma, &range.start, &range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); address = start; for (; address < end; address += sz) { ptep = huge_pte_offset(mm, address, sz); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { @@ -6305,6 +6320,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, unsigned long pages = 0, psize = huge_page_size(h); bool shared_pmd = false; struct mmu_notifier_range range; + unsigned long last_addr_mask; bool uffd_wp = cp_flags & MM_CP_UFFD_WP; bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE; @@ -6321,12 +6337,15 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); i_mmap_lock_write(vma->vm_file->f_mapping); for (; address < end; address += psize) { spinlock_t *ptl; ptep = huge_pte_offset(mm, address, psize); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { /* @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return (pte_t *)pmd; } +/* + * Return a mask that can be used to update an address to the last huge + * page in a page table page mapping size. Used to skip non-present + * page table entries when linearly scanning address ranges. Architectures + * with unique huge page to page table relationships can define their own + * version of this routine. + */ +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case P4D_SIZE: + return PGDIR_SIZE - P4D_SIZE; + case PUD_SIZE: + return P4D_SIZE - PUD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + default: + break; /* Should never happen */ + } + + return ~(0UL); +} + +#else + +/* See description above. Architectures can provide their own version. */ +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + return ~(0UL); +} + #endif /* CONFIG_ARCH_WANT_GENERAL_HUGETLB */ /* -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz HugeTLB address ranges are linearly scanned during fork, unmap and remap operations. If a non-present entry is encountered, the code currently continues to the next huge page aligned address. However, a non-present entry implies that the page table page for that entry is not present. Therefore, the linear scan can skip to the end of range mapped by the page table page. This can speed operations on large sparsely populated hugetlb mappings. Create a new routine hugetlb_mask_last_page() that will return an address mask. When the mask is ORed with an address, the result will be the address of the last huge page mapped by the associated page table page. Use this mask to update addresses in routines which linearly scan hugetlb address ranges when a non-present pte is encountered. hugetlb_mask_last_page is related to the implementation of huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset returns NULL. This patch only provides a complete hugetlb_mask_last_page implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. Architectures which provide their own versions of huge_pte_offset can also provide their own version of hugetlb_mask_last_page. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 1 + mm/hugetlb.c | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 642a39016f9a..e37465e830fe 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -197,6 +197,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz); pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); +unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long *addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 259b9c41892f..7c4a82848603 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4740,6 +4740,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, unsigned long npages = pages_per_huge_page(h); struct address_space *mapping = src_vma->vm_file->f_mapping; struct mmu_notifier_range range; + unsigned long last_addr_mask; int ret = 0; if (cow) { @@ -4759,11 +4760,14 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, i_mmap_lock_read(mapping); } + last_addr_mask = hugetlb_mask_last_page(h); for (addr = src_vma->vm_start; addr < src_vma->vm_end; addr += sz) { spinlock_t *src_ptl, *dst_ptl; src_pte = huge_pte_offset(src, addr, sz); - if (!src_pte) + if (!src_pte) { + addr |= last_addr_mask; continue; + } dst_pte = huge_pte_alloc(dst, dst_vma, addr, sz); if (!dst_pte) { ret = -ENOMEM; @@ -4780,8 +4784,10 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, * after taking the lock below. */ dst_entry = huge_ptep_get(dst_pte); - if ((dst_pte = src_pte) || !huge_pte_none(dst_entry)) + if ((dst_pte = src_pte) || !huge_pte_none(dst_entry)) { + addr |= last_addr_mask; continue; + } dst_ptl = huge_pte_lock(h, dst, dst_pte); src_ptl = huge_pte_lockptr(h, src, src_pte); @@ -4942,6 +4948,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, unsigned long sz = huge_page_size(h); struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; + unsigned long last_addr_mask; unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; @@ -4957,12 +4964,16 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); /* Prevent race with file truncation */ i_mmap_lock_write(mapping); for (; old_addr < old_end; old_addr += sz, new_addr += sz) { src_pte = huge_pte_offset(mm, old_addr, sz); - if (!src_pte) + if (!src_pte) { + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; + } if (huge_pte_none(huge_ptep_get(src_pte))) continue; @@ -5007,6 +5018,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); struct mmu_notifier_range range; + unsigned long last_addr_mask; bool force_flush = false; WARN_ON(!is_vm_hugetlb_page(vma)); @@ -5027,11 +5039,14 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct end); adjust_range_if_pmd_sharing_possible(vma, &range.start, &range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); address = start; for (; address < end; address += sz) { ptep = huge_pte_offset(mm, address, sz); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { @@ -6305,6 +6320,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, unsigned long pages = 0, psize = huge_page_size(h); bool shared_pmd = false; struct mmu_notifier_range range; + unsigned long last_addr_mask; bool uffd_wp = cp_flags & MM_CP_UFFD_WP; bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE; @@ -6321,12 +6337,15 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, flush_cache_range(vma, range.start, range.end); mmu_notifier_invalidate_range_start(&range); + last_addr_mask = hugetlb_mask_last_page(h); i_mmap_lock_write(vma->vm_file->f_mapping); for (; address < end; address += psize) { spinlock_t *ptl; ptep = huge_pte_offset(mm, address, psize); - if (!ptep) + if (!ptep) { + address |= last_addr_mask; continue; + } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { /* @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return (pte_t *)pmd; } +/* + * Return a mask that can be used to update an address to the last huge + * page in a page table page mapping size. Used to skip non-present + * page table entries when linearly scanning address ranges. Architectures + * with unique huge page to page table relationships can define their own + * version of this routine. + */ +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case P4D_SIZE: + return PGDIR_SIZE - P4D_SIZE; + case PUD_SIZE: + return P4D_SIZE - PUD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + default: + break; /* Should never happen */ + } + + return ~(0UL); +} + +#else + +/* See description above. Architectures can provide their own version. */ +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + return ~(0UL); +} + #endif /* CONFIG_ARCH_WANT_GENERAL_HUGETLB */ /* -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-17 8:13 ` Muchun Song -1 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:13 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations. If a non-present entry is encountered, the code > currently continues to the next huge page aligned address. However, > a non-present entry implies that the page table page for that entry > is not present. Therefore, the linear scan can skip to the end of > range mapped by the page table page. This can speed operations on > large sparsely populated hugetlb mappings. > > Create a new routine hugetlb_mask_last_page() that will return an > address mask. When the mask is ORed with an address, the result > will be the address of the last huge page mapped by the associated > page table page. Use this mask to update addresses in routines which > linearly scan hugetlb address ranges when a non-present pte is > encountered. > > hugetlb_mask_last_page is related to the implementation of > huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset > returns NULL. This patch only provides a complete hugetlb_mask_last_page > implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. > Architectures which provide their own versions of huge_pte_offset can also > provide their own version of hugetlb_mask_last_page. > > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> > Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> It'll be more efficient, Thanks. Acked-by: Muchun Song <songmuchun@bytedance.com> ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 8:13 ` Muchun Song 0 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:13 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations. If a non-present entry is encountered, the code > currently continues to the next huge page aligned address. However, > a non-present entry implies that the page table page for that entry > is not present. Therefore, the linear scan can skip to the end of > range mapped by the page table page. This can speed operations on > large sparsely populated hugetlb mappings. > > Create a new routine hugetlb_mask_last_page() that will return an > address mask. When the mask is ORed with an address, the result > will be the address of the last huge page mapped by the associated > page table page. Use this mask to update addresses in routines which > linearly scan hugetlb address ranges when a non-present pte is > encountered. > > hugetlb_mask_last_page is related to the implementation of > huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset > returns NULL. This patch only provides a complete hugetlb_mask_last_page > implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. > Architectures which provide their own versions of huge_pte_offset can also > provide their own version of hugetlb_mask_last_page. > > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> > Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> It'll be more efficient, Thanks. Acked-by: Muchun Song <songmuchun@bytedance.com> _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 8:13 ` Muchun Song 0 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:13 UTC (permalink / raw) To: Mike Kravetz Cc: Michal Hocko, linux-ia64, linux-sh, catalin.marinas, Peter Xu, linux-mips, linux-mm, James Houghton, sparclinux, will, Mina Almasry, linux-s390, Christian Borntraeger, Anshuman Khandual, Baolin Wang, Paul Walmsley, Naoya Horiguchi, linux-arm-kernel, linux-parisc, linux-kernel, Aneesh Kumar K . V, Andrew Morton, linuxppc-dev On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations. If a non-present entry is encountered, the code > currently continues to the next huge page aligned address. However, > a non-present entry implies that the page table page for that entry > is not present. Therefore, the linear scan can skip to the end of > range mapped by the page table page. This can speed operations on > large sparsely populated hugetlb mappings. > > Create a new routine hugetlb_mask_last_page() that will return an > address mask. When the mask is ORed with an address, the result > will be the address of the last huge page mapped by the associated > page table page. Use this mask to update addresses in routines which > linearly scan hugetlb address ranges when a non-present pte is > encountered. > > hugetlb_mask_last_page is related to the implementation of > huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset > returns NULL. This patch only provides a complete hugetlb_mask_last_page > implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. > Architectures which provide their own versions of huge_pte_offset can also > provide their own version of hugetlb_mask_last_page. > > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> > Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> It'll be more efficient, Thanks. Acked-by: Muchun Song <songmuchun@bytedance.com> ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 8:13 ` Muchun Song 0 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:13 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations. If a non-present entry is encountered, the code > currently continues to the next huge page aligned address. However, > a non-present entry implies that the page table page for that entry > is not present. Therefore, the linear scan can skip to the end of > range mapped by the page table page. This can speed operations on > large sparsely populated hugetlb mappings. > > Create a new routine hugetlb_mask_last_page() that will return an > address mask. When the mask is ORed with an address, the result > will be the address of the last huge page mapped by the associated > page table page. Use this mask to update addresses in routines which > linearly scan hugetlb address ranges when a non-present pte is > encountered. > > hugetlb_mask_last_page is related to the implementation of > huge_pte_offset as hugetlb_mask_last_page is called when huge_pte_offset > returns NULL. This patch only provides a complete hugetlb_mask_last_page > implementation when CONFIG_ARCH_WANT_GENERAL_HUGETLB is defined. > Architectures which provide their own versions of huge_pte_offset can also > provide their own version of hugetlb_mask_last_page. > > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> > Tested-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> It'll be more efficient, Thanks. Acked-by: Muchun Song <songmuchun@bytedance.com> ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-17 11:26 ` kernel test robot -1 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 11:26 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: llvm, kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Linux Memory Management List, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ mm/hugetlb.c:6899:7: note: previous case defined here case P4D_SIZE: ^ include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' #define P4D_SIZE (1UL << P4D_SHIFT) ^ mm/hugetlb.c:6903:7: error: duplicate case value '4194304' case PMD_SIZE: ^ include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' #define PMD_SIZE (1UL << PMD_SHIFT) ^ mm/hugetlb.c:6901:7: note: previous case defined here case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ 2 errors generated. vim +/4194304 +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 11:26 ` kernel test robot 0 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 11:26 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: llvm, kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Linux Memory Management List, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ mm/hugetlb.c:6899:7: note: previous case defined here case P4D_SIZE: ^ include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' #define P4D_SIZE (1UL << P4D_SHIFT) ^ mm/hugetlb.c:6903:7: error: duplicate case value '4194304' case PMD_SIZE: ^ include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' #define PMD_SIZE (1UL << PMD_SHIFT) ^ mm/hugetlb.c:6901:7: note: previous case defined here case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ 2 errors generated. vim +/4194304 +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 11:26 ` kernel test robot 0 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 11:26 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Mina Almasry, Michal Hocko, kbuild-all, will, Anshuman Khandual, catalin.marinas, llvm, Peter Xu, Paul Walmsley, Linux Memory Management List, James Houghton, Aneesh Kumar K . V, Baolin Wang, Muchun Song, Andrew Morton, Christian Borntraeger, Naoya Horiguchi, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ mm/hugetlb.c:6899:7: note: previous case defined here case P4D_SIZE: ^ include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' #define P4D_SIZE (1UL << P4D_SHIFT) ^ mm/hugetlb.c:6903:7: error: duplicate case value '4194304' case PMD_SIZE: ^ include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' #define PMD_SIZE (1UL << PMD_SHIFT) ^ mm/hugetlb.c:6901:7: note: previous case defined here case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ 2 errors generated. vim +/4194304 +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 11:26 ` kernel test robot 0 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 11:26 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: llvm, kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ mm/hugetlb.c:6899:7: note: previous case defined here case P4D_SIZE: ^ include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' #define P4D_SIZE (1UL << P4D_SHIFT) ^ mm/hugetlb.c:6903:7: error: duplicate case value '4194304' case PMD_SIZE: ^ include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' #define PMD_SIZE (1UL << PMD_SHIFT) ^ mm/hugetlb.c:6901:7: note: previous case defined here case PUD_SIZE: ^ include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' #define PUD_SIZE (1UL << PUD_SHIFT) ^ 2 errors generated. vim +/4194304 +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-17 11:26 ` kernel test robot ` (2 preceding siblings ...) (?) @ 2022-06-17 21:09 ` Mike Kravetz -1 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 21:09 UTC (permalink / raw) To: kernel test robot Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, llvm, kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 06/17/22 19:26, kernel test robot wrote: > Hi Mike, > > I love your patch! Yet something to improve: > > [auto build test ERROR on soc/for-next] > [also build test ERROR on linus/master v5.19-rc2 next-20220617] > [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] > [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] > > url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next > config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) > compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) > reproduce (this is a W=1 build): > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 > git remote add linux-review https://github.com/intel-lab-lkp/linux > git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > git checkout 4c647687607f10fece04967b8180c0dadaf765e6 > # save the config file > mkdir build_dir && cp config build_dir/.config > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash > > If you fix the issue, kindly add following tag where applicable > Reported-by: kernel test robot <lkp@intel.com> > > All errors (new ones prefixed by >>): A couple of things here, > > >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' > case PUD_SIZE: > ^ > include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' > #define PUD_SIZE (1UL << PUD_SHIFT) > ^ > mm/hugetlb.c:6899:7: note: previous case defined here > case P4D_SIZE: > ^ > include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' > #define P4D_SIZE (1UL << P4D_SHIFT) In the CONFIG_ARCH_WANT_GENERAL_HUGETLB case covered by this version of hugetlb_mask_last_page, huge pages can only be PMD_SIZE or PUD_SIZE. So, the 'case P4D_SIZE:' should not exist and can be removed. > ^ > mm/hugetlb.c:6903:7: error: duplicate case value '4194304' > case PMD_SIZE: > ^ > include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' > #define PMD_SIZE (1UL << PMD_SHIFT) > ^ On i386 with CONFIG_PGTABLE_LEVELS=2, PUD_SIZE == PMD_SIZE. Originally, I coded this as a if .. else if ... statement instead of a switch. If coded this way, the compiler does not complain about the duplicate values. The only other alternative I can think of is something like '#if CONFIG_PGTABLE_LEVELS > 2' around the PUD_SIZE case. I would prefer the if else if, unless someone can suggest something else? -- Mike Kravetz ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 21:09 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 21:09 UTC (permalink / raw) To: kernel test robot Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, llvm, kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 06/17/22 19:26, kernel test robot wrote: > Hi Mike, > > I love your patch! Yet something to improve: > > [auto build test ERROR on soc/for-next] > [also build test ERROR on linus/master v5.19-rc2 next-20220617] > [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] > [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] > > url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next > config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) > compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) > reproduce (this is a W=1 build): > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 > git remote add linux-review https://github.com/intel-lab-lkp/linux > git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > git checkout 4c647687607f10fece04967b8180c0dadaf765e6 > # save the config file > mkdir build_dir && cp config build_dir/.config > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash > > If you fix the issue, kindly add following tag where applicable > Reported-by: kernel test robot <lkp@intel.com> > > All errors (new ones prefixed by >>): A couple of things here, > > >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' > case PUD_SIZE: > ^ > include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' > #define PUD_SIZE (1UL << PUD_SHIFT) > ^ > mm/hugetlb.c:6899:7: note: previous case defined here > case P4D_SIZE: > ^ > include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' > #define P4D_SIZE (1UL << P4D_SHIFT) In the CONFIG_ARCH_WANT_GENERAL_HUGETLB case covered by this version of hugetlb_mask_last_page, huge pages can only be PMD_SIZE or PUD_SIZE. So, the 'case P4D_SIZE:' should not exist and can be removed. > ^ > mm/hugetlb.c:6903:7: error: duplicate case value '4194304' > case PMD_SIZE: > ^ > include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' > #define PMD_SIZE (1UL << PMD_SHIFT) > ^ On i386 with CONFIG_PGTABLE_LEVELS=2, PUD_SIZE == PMD_SIZE. Originally, I coded this as a if .. else if ... statement instead of a switch. If coded this way, the compiler does not complain about the duplicate values. The only other alternative I can think of is something like '#if CONFIG_PGTABLE_LEVELS > 2' around the PUD_SIZE case. I would prefer the if else if, unless someone can suggest something else? -- Mike Kravetz _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 21:09 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 21:09 UTC (permalink / raw) To: kernel test robot Cc: Michal Hocko, linux-ia64, linux-sh, catalin.marinas, llvm, Peter Xu, linux-mips, linux-mm, James Houghton, sparclinux, will, Mina Almasry, linux-s390, linux-arm-kernel, Christian Borntraeger, Anshuman Khandual, Baolin Wang, Paul Walmsley, Naoya Horiguchi, Muchun Song, kbuild-all, linux-parisc, linux-kernel, Aneesh Kumar K . V, Andrew Morton, linuxppc-dev On 06/17/22 19:26, kernel test robot wrote: > Hi Mike, > > I love your patch! Yet something to improve: > > [auto build test ERROR on soc/for-next] > [also build test ERROR on linus/master v5.19-rc2 next-20220617] > [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] > [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] > > url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next > config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) > compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) > reproduce (this is a W=1 build): > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 > git remote add linux-review https://github.com/intel-lab-lkp/linux > git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > git checkout 4c647687607f10fece04967b8180c0dadaf765e6 > # save the config file > mkdir build_dir && cp config build_dir/.config > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash > > If you fix the issue, kindly add following tag where applicable > Reported-by: kernel test robot <lkp@intel.com> > > All errors (new ones prefixed by >>): A couple of things here, > > >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' > case PUD_SIZE: > ^ > include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' > #define PUD_SIZE (1UL << PUD_SHIFT) > ^ > mm/hugetlb.c:6899:7: note: previous case defined here > case P4D_SIZE: > ^ > include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' > #define P4D_SIZE (1UL << P4D_SHIFT) In the CONFIG_ARCH_WANT_GENERAL_HUGETLB case covered by this version of hugetlb_mask_last_page, huge pages can only be PMD_SIZE or PUD_SIZE. So, the 'case P4D_SIZE:' should not exist and can be removed. > ^ > mm/hugetlb.c:6903:7: error: duplicate case value '4194304' > case PMD_SIZE: > ^ > include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' > #define PMD_SIZE (1UL << PMD_SHIFT) > ^ On i386 with CONFIG_PGTABLE_LEVELS=2, PUD_SIZE == PMD_SIZE. Originally, I coded this as a if .. else if ... statement instead of a switch. If coded this way, the compiler does not complain about the duplicate values. The only other alternative I can think of is something like '#if CONFIG_PGTABLE_LEVELS > 2' around the PUD_SIZE case. I would prefer the if else if, unless someone can suggest something else? -- Mike Kravetz ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 21:09 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 21:09 UTC (permalink / raw) To: kernel test robot Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, llvm, kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 06/17/22 19:26, kernel test robot wrote: > Hi Mike, > > I love your patch! Yet something to improve: > > [auto build test ERROR on soc/for-next] > [also build test ERROR on linus/master v5.19-rc2 next-20220617] > [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] > [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] > > url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next > config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp@intel.com/config) > compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) > reproduce (this is a W=1 build): > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 > git remote add linux-review https://github.com/intel-lab-lkp/linux > git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > git checkout 4c647687607f10fece04967b8180c0dadaf765e6 > # save the config file > mkdir build_dir && cp config build_dir/.config > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash > > If you fix the issue, kindly add following tag where applicable > Reported-by: kernel test robot <lkp@intel.com> > > All errors (new ones prefixed by >>): A couple of things here, > > >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' > case PUD_SIZE: > ^ > include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' > #define PUD_SIZE (1UL << PUD_SHIFT) > ^ > mm/hugetlb.c:6899:7: note: previous case defined here > case P4D_SIZE: > ^ > include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' > #define P4D_SIZE (1UL << P4D_SHIFT) In the CONFIG_ARCH_WANT_GENERAL_HUGETLB case covered by this version of hugetlb_mask_last_page, huge pages can only be PMD_SIZE or PUD_SIZE. So, the 'case P4D_SIZE:' should not exist and can be removed. > ^ > mm/hugetlb.c:6903:7: error: duplicate case value '4194304' > case PMD_SIZE: > ^ > include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' > #define PMD_SIZE (1UL << PMD_SHIFT) > ^ On i386 with CONFIG_PGTABLE_LEVELS=2, PUD_SIZE = PMD_SIZE. Originally, I coded this as a if .. else if ... statement instead of a switch. If coded this way, the compiler does not complain about the duplicate values. The only other alternative I can think of is something like '#if CONFIG_PGTABLE_LEVELS > 2' around the PUD_SIZE case. I would prefer the if else if, unless someone can suggest something else? -- Mike Kravetz ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 21:09 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 21:09 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 3405 bytes --] On 06/17/22 19:26, kernel test robot wrote: > Hi Mike, > > I love your patch! Yet something to improve: > > [auto build test ERROR on soc/for-next] > [also build test ERROR on linus/master v5.19-rc2 next-20220617] > [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] > [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] > > url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next > config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20220617/202206171929.ZIUrNg6p-lkp(a)intel.com/config) > compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project f0e608de27b3d568000046eebf3712ab542979d6) > reproduce (this is a W=1 build): > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 > git remote add linux-review https://github.com/intel-lab-lkp/linux > git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 > git checkout 4c647687607f10fece04967b8180c0dadaf765e6 > # save the config file > mkdir build_dir && cp config build_dir/.config > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash > > If you fix the issue, kindly add following tag where applicable > Reported-by: kernel test robot <lkp@intel.com> > > All errors (new ones prefixed by >>): A couple of things here, > > >> mm/hugetlb.c:6901:7: error: duplicate case value '4194304' > case PUD_SIZE: > ^ > include/asm-generic/pgtable-nopud.h:20:20: note: expanded from macro 'PUD_SIZE' > #define PUD_SIZE (1UL << PUD_SHIFT) > ^ > mm/hugetlb.c:6899:7: note: previous case defined here > case P4D_SIZE: > ^ > include/asm-generic/pgtable-nop4d.h:13:19: note: expanded from macro 'P4D_SIZE' > #define P4D_SIZE (1UL << P4D_SHIFT) In the CONFIG_ARCH_WANT_GENERAL_HUGETLB case covered by this version of hugetlb_mask_last_page, huge pages can only be PMD_SIZE or PUD_SIZE. So, the 'case P4D_SIZE:' should not exist and can be removed. > ^ > mm/hugetlb.c:6903:7: error: duplicate case value '4194304' > case PMD_SIZE: > ^ > include/asm-generic/pgtable-nopmd.h:22:20: note: expanded from macro 'PMD_SIZE' > #define PMD_SIZE (1UL << PMD_SHIFT) > ^ On i386 with CONFIG_PGTABLE_LEVELS=2, PUD_SIZE == PMD_SIZE. Originally, I coded this as a if .. else if ... statement instead of a switch. If coded this way, the compiler does not complain about the duplicate values. The only other alternative I can think of is something like '#if CONFIG_PGTABLE_LEVELS > 2' around the PUD_SIZE case. I would prefer the if else if, unless someone can suggest something else? -- Mike Kravetz ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-17 14:15 ` Peter Xu -1 siblings, 0 replies; 57+ messages in thread From: Peter Xu @ 2022-06-17 14:15 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton Hi, Mike, On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > return (pte_t *)pmd; > } > > +/* > + * Return a mask that can be used to update an address to the last huge > + * page in a page table page mapping size. Used to skip non-present > + * page table entries when linearly scanning address ranges. Architectures > + * with unique huge page to page table relationships can define their own > + * version of this routine. > + */ > +unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + unsigned long hp_size = huge_page_size(h); > + > + switch (hp_size) { > + case P4D_SIZE: > + return PGDIR_SIZE - P4D_SIZE; > + case PUD_SIZE: > + return P4D_SIZE - PUD_SIZE; > + case PMD_SIZE: > + return PUD_SIZE - PMD_SIZE; > + default: Should we add a WARN_ON_ONCE() if it should never trigger? > + break; /* Should never happen */ > + } > + > + return ~(0UL); > +} > + > +#else > + > +/* See description above. Architectures can provide their own version. */ > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + return ~(0UL); I'm wondering whether it's better to return 0 rather than ~0 by default. Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some valid address ranges with ~0, or perhaps I misread? Thanks, -- Peter Xu ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 14:15 ` Peter Xu 0 siblings, 0 replies; 57+ messages in thread From: Peter Xu @ 2022-06-17 14:15 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton Hi, Mike, On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > return (pte_t *)pmd; > } > > +/* > + * Return a mask that can be used to update an address to the last huge > + * page in a page table page mapping size. Used to skip non-present > + * page table entries when linearly scanning address ranges. Architectures > + * with unique huge page to page table relationships can define their own > + * version of this routine. > + */ > +unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + unsigned long hp_size = huge_page_size(h); > + > + switch (hp_size) { > + case P4D_SIZE: > + return PGDIR_SIZE - P4D_SIZE; > + case PUD_SIZE: > + return P4D_SIZE - PUD_SIZE; > + case PMD_SIZE: > + return PUD_SIZE - PMD_SIZE; > + default: Should we add a WARN_ON_ONCE() if it should never trigger? > + break; /* Should never happen */ > + } > + > + return ~(0UL); > +} > + > +#else > + > +/* See description above. Architectures can provide their own version. */ > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + return ~(0UL); I'm wondering whether it's better to return 0 rather than ~0 by default. Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some valid address ranges with ~0, or perhaps I misread? Thanks, -- Peter Xu _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 14:15 ` Peter Xu 0 siblings, 0 replies; 57+ messages in thread From: Peter Xu @ 2022-06-17 14:15 UTC (permalink / raw) To: Mike Kravetz Cc: Michal Hocko, linux-ia64, linux-sh, catalin.marinas, Muchun Song, linux-mips, linux-mm, James Houghton, sparclinux, will, Mina Almasry, linux-s390, Christian Borntraeger, Anshuman Khandual, Baolin Wang, Paul Walmsley, Naoya Horiguchi, linux-arm-kernel, linux-parisc, linux-kernel, Aneesh Kumar K . V, Andrew Morton, linuxppc-dev Hi, Mike, On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > return (pte_t *)pmd; > } > > +/* > + * Return a mask that can be used to update an address to the last huge > + * page in a page table page mapping size. Used to skip non-present > + * page table entries when linearly scanning address ranges. Architectures > + * with unique huge page to page table relationships can define their own > + * version of this routine. > + */ > +unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + unsigned long hp_size = huge_page_size(h); > + > + switch (hp_size) { > + case P4D_SIZE: > + return PGDIR_SIZE - P4D_SIZE; > + case PUD_SIZE: > + return P4D_SIZE - PUD_SIZE; > + case PMD_SIZE: > + return PUD_SIZE - PMD_SIZE; > + default: Should we add a WARN_ON_ONCE() if it should never trigger? > + break; /* Should never happen */ > + } > + > + return ~(0UL); > +} > + > +#else > + > +/* See description above. Architectures can provide their own version. */ > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + return ~(0UL); I'm wondering whether it's better to return 0 rather than ~0 by default. Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some valid address ranges with ~0, or perhaps I misread? Thanks, -- Peter Xu ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 14:15 ` Peter Xu 0 siblings, 0 replies; 57+ messages in thread From: Peter Xu @ 2022-06-17 14:15 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton Hi, Mike, On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > return (pte_t *)pmd; > } > > +/* > + * Return a mask that can be used to update an address to the last huge > + * page in a page table page mapping size. Used to skip non-present > + * page table entries when linearly scanning address ranges. Architectures > + * with unique huge page to page table relationships can define their own > + * version of this routine. > + */ > +unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + unsigned long hp_size = huge_page_size(h); > + > + switch (hp_size) { > + case P4D_SIZE: > + return PGDIR_SIZE - P4D_SIZE; > + case PUD_SIZE: > + return P4D_SIZE - PUD_SIZE; > + case PMD_SIZE: > + return PUD_SIZE - PMD_SIZE; > + default: Should we add a WARN_ON_ONCE() if it should never trigger? > + break; /* Should never happen */ > + } > + > + return ~(0UL); > +} > + > +#else > + > +/* See description above. Architectures can provide their own version. */ > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > +{ > + return ~(0UL); I'm wondering whether it's better to return 0 rather than ~0 by default. Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some valid address ranges with ~0, or perhaps I misread? Thanks, -- Peter Xu ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-17 14:15 ` Peter Xu (?) (?) @ 2022-06-17 15:26 ` Geert Uytterhoeven -1 siblings, 0 replies; 57+ messages in thread From: Geert Uytterhoeven @ 2022-06-17 15:26 UTC (permalink / raw) To: Peter Xu Cc: Mike Kravetz, Linux Kernel Mailing List, Linux MM, Linux ARM, linux-s390, Linux-sh list, sparclinux, linux-ia64@vger.kernel.org, open list:BROADCOM NVRAM DRIVER, Parisc List, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, Catalin Marinas, Will Deacon, Andrew Morton Hi Peter, On Fri, Jun 17, 2022 at 4:22 PM Peter Xu <peterx@redhat.com> wrote: > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? And with panic_on_warn, it'll panic only once ;-) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 15:26 ` Geert Uytterhoeven 0 siblings, 0 replies; 57+ messages in thread From: Geert Uytterhoeven @ 2022-06-17 15:26 UTC (permalink / raw) To: Peter Xu Cc: Mike Kravetz, Linux Kernel Mailing List, Linux MM, Linux ARM, linux-s390, Linux-sh list, sparclinux, linux-ia64@vger.kernel.org, open list:BROADCOM NVRAM DRIVER, Parisc List, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, Catalin Marinas, Will Deacon, Andrew Morton Hi Peter, On Fri, Jun 17, 2022 at 4:22 PM Peter Xu <peterx@redhat.com> wrote: > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? And with panic_on_warn, it'll panic only once ;-) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 15:26 ` Geert Uytterhoeven 0 siblings, 0 replies; 57+ messages in thread From: Geert Uytterhoeven @ 2022-06-17 15:26 UTC (permalink / raw) To: Peter Xu Cc: Michal Hocko, linux-ia64@vger.kernel.org, Linux-sh list, Catalin Marinas, Muchun Song, open list:BROADCOM NVRAM DRIVER, Linux MM, James Houghton, sparclinux, Will Deacon, Mina Almasry, linux-s390, Christian Borntraeger, Anshuman Khandual, Baolin Wang, Paul Walmsley, Naoya Horiguchi, Linux ARM, Parisc List, Linux Kernel Mailing List, Aneesh Kumar K . V, Andrew Morton, linuxppc-d ev, Mike Kravetz Hi Peter, On Fri, Jun 17, 2022 at 4:22 PM Peter Xu <peterx@redhat.com> wrote: > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? And with panic_on_warn, it'll panic only once ;-) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 15:26 ` Geert Uytterhoeven 0 siblings, 0 replies; 57+ messages in thread From: Geert Uytterhoeven @ 2022-06-17 15:26 UTC (permalink / raw) To: Peter Xu Cc: Mike Kravetz, Linux Kernel Mailing List, Linux MM, Linux ARM, linux-s390, Linux-sh list, sparclinux, linux-ia64@vger.kernel.org, open list:BROADCOM NVRAM DRIVER, Parisc List, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, Catalin Marinas, Will Deacon, Andrew Morton Hi Peter, On Fri, Jun 17, 2022 at 4:22 PM Peter Xu <peterx@redhat.com> wrote: > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? And with panic_on_warn, it'll panic only once ;-) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-17 14:15 ` Peter Xu (?) (?) @ 2022-06-17 17:17 ` Mike Kravetz -1 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 17:17 UTC (permalink / raw) To: Peter Xu Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 06/17/22 10:15, Peter Xu wrote: > Hi, Mike, > > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? > Sure. I will add this. > > + break; /* Should never happen */ > > + } > > + > > + return ~(0UL); > > +} > > + > > +#else > > + > > +/* See description above. Architectures can provide their own version. */ > > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + return ~(0UL); > > I'm wondering whether it's better to return 0 rather than ~0 by default. > Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some > valid address ranges with ~0, or perhaps I misread? Thank you, thank you, thank you Peter! Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If there is no 'optimization', we do not want to modify the address so we want to OR with 0 not ~0. My bad, I must have been thinking AND instead of OR. I will change here as well as in Baolin's patch. -- Mike Kravetz ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 17:17 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 17:17 UTC (permalink / raw) To: Peter Xu Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 06/17/22 10:15, Peter Xu wrote: > Hi, Mike, > > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? > Sure. I will add this. > > + break; /* Should never happen */ > > + } > > + > > + return ~(0UL); > > +} > > + > > +#else > > + > > +/* See description above. Architectures can provide their own version. */ > > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + return ~(0UL); > > I'm wondering whether it's better to return 0 rather than ~0 by default. > Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some > valid address ranges with ~0, or perhaps I misread? Thank you, thank you, thank you Peter! Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If there is no 'optimization', we do not want to modify the address so we want to OR with 0 not ~0. My bad, I must have been thinking AND instead of OR. I will change here as well as in Baolin's patch. -- Mike Kravetz _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 17:17 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 17:17 UTC (permalink / raw) To: Peter Xu Cc: Michal Hocko, linux-ia64, linux-sh, catalin.marinas, Muchun Song, linux-mips, linux-mm, James Houghton, sparclinux, will, Mina Almasry, linux-s390, Christian Borntraeger, Anshuman Khandual, Baolin Wang, Paul Walmsley, Naoya Horiguchi, linux-arm-kernel, linux-parisc, linux-kernel, Aneesh Kumar K . V, Andrew Morton, linuxppc-dev On 06/17/22 10:15, Peter Xu wrote: > Hi, Mike, > > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? > Sure. I will add this. > > + break; /* Should never happen */ > > + } > > + > > + return ~(0UL); > > +} > > + > > +#else > > + > > +/* See description above. Architectures can provide their own version. */ > > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + return ~(0UL); > > I'm wondering whether it's better to return 0 rather than ~0 by default. > Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some > valid address ranges with ~0, or perhaps I misread? Thank you, thank you, thank you Peter! Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If there is no 'optimization', we do not want to modify the address so we want to OR with 0 not ~0. My bad, I must have been thinking AND instead of OR. I will change here as well as in Baolin's patch. -- Mike Kravetz ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 17:17 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-17 17:17 UTC (permalink / raw) To: Peter Xu Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Baolin Wang, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 06/17/22 10:15, Peter Xu wrote: > Hi, Mike, > > On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: > > @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, > > return (pte_t *)pmd; > > } > > > > +/* > > + * Return a mask that can be used to update an address to the last huge > > + * page in a page table page mapping size. Used to skip non-present > > + * page table entries when linearly scanning address ranges. Architectures > > + * with unique huge page to page table relationships can define their own > > + * version of this routine. > > + */ > > +unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + unsigned long hp_size = huge_page_size(h); > > + > > + switch (hp_size) { > > + case P4D_SIZE: > > + return PGDIR_SIZE - P4D_SIZE; > > + case PUD_SIZE: > > + return P4D_SIZE - PUD_SIZE; > > + case PMD_SIZE: > > + return PUD_SIZE - PMD_SIZE; > > + default: > > Should we add a WARN_ON_ONCE() if it should never trigger? > Sure. I will add this. > > + break; /* Should never happen */ > > + } > > + > > + return ~(0UL); > > +} > > + > > +#else > > + > > +/* See description above. Architectures can provide their own version. */ > > +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) > > +{ > > + return ~(0UL); > > I'm wondering whether it's better to return 0 rather than ~0 by default. > Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some > valid address ranges with ~0, or perhaps I misread? Thank you, thank you, thank you Peter! Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If there is no 'optimization', we do not want to modify the address so we want to OR with 0 not ~0. My bad, I must have been thinking AND instead of OR. I will change here as well as in Baolin's patch. -- Mike Kravetz ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-17 17:17 ` Mike Kravetz (?) (?) @ 2022-06-18 3:27 ` Baolin Wang -1 siblings, 0 replies; 57+ messages in thread From: Baolin Wang @ 2022-06-18 3:27 UTC (permalink / raw) To: Mike Kravetz, Peter Xu Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 6/18/2022 1:17 AM, Mike Kravetz wrote: > On 06/17/22 10:15, Peter Xu wrote: >> Hi, Mike, >> >> On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: >>> @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, >>> return (pte_t *)pmd; >>> } >>> >>> +/* >>> + * Return a mask that can be used to update an address to the last huge >>> + * page in a page table page mapping size. Used to skip non-present >>> + * page table entries when linearly scanning address ranges. Architectures >>> + * with unique huge page to page table relationships can define their own >>> + * version of this routine. >>> + */ >>> +unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + unsigned long hp_size = huge_page_size(h); >>> + >>> + switch (hp_size) { >>> + case P4D_SIZE: >>> + return PGDIR_SIZE - P4D_SIZE; >>> + case PUD_SIZE: >>> + return P4D_SIZE - PUD_SIZE; >>> + case PMD_SIZE: >>> + return PUD_SIZE - PMD_SIZE; >>> + default: >> >> Should we add a WARN_ON_ONCE() if it should never trigger? >> > > Sure. I will add this. > >>> + break; /* Should never happen */ >>> + } >>> + >>> + return ~(0UL); >>> +} >>> + >>> +#else >>> + >>> +/* See description above. Architectures can provide their own version. */ >>> +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + return ~(0UL); >> >> I'm wondering whether it's better to return 0 rather than ~0 by default. >> Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some >> valid address ranges with ~0, or perhaps I misread? > > Thank you, thank you, thank you Peter! > > Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If > there is no 'optimization', we do not want to modify the address so we > want to OR with 0 not ~0. My bad, I must have been thinking AND instead > of OR. > > I will change here as well as in Baolin's patch. Ah, I also overlooked this. Thanks Peter, and thanks Mike for updating. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-18 3:27 ` Baolin Wang 0 siblings, 0 replies; 57+ messages in thread From: Baolin Wang @ 2022-06-18 3:27 UTC (permalink / raw) To: Mike Kravetz, Peter Xu Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 6/18/2022 1:17 AM, Mike Kravetz wrote: > On 06/17/22 10:15, Peter Xu wrote: >> Hi, Mike, >> >> On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: >>> @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, >>> return (pte_t *)pmd; >>> } >>> >>> +/* >>> + * Return a mask that can be used to update an address to the last huge >>> + * page in a page table page mapping size. Used to skip non-present >>> + * page table entries when linearly scanning address ranges. Architectures >>> + * with unique huge page to page table relationships can define their own >>> + * version of this routine. >>> + */ >>> +unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + unsigned long hp_size = huge_page_size(h); >>> + >>> + switch (hp_size) { >>> + case P4D_SIZE: >>> + return PGDIR_SIZE - P4D_SIZE; >>> + case PUD_SIZE: >>> + return P4D_SIZE - PUD_SIZE; >>> + case PMD_SIZE: >>> + return PUD_SIZE - PMD_SIZE; >>> + default: >> >> Should we add a WARN_ON_ONCE() if it should never trigger? >> > > Sure. I will add this. > >>> + break; /* Should never happen */ >>> + } >>> + >>> + return ~(0UL); >>> +} >>> + >>> +#else >>> + >>> +/* See description above. Architectures can provide their own version. */ >>> +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + return ~(0UL); >> >> I'm wondering whether it's better to return 0 rather than ~0 by default. >> Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some >> valid address ranges with ~0, or perhaps I misread? > > Thank you, thank you, thank you Peter! > > Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If > there is no 'optimization', we do not want to modify the address so we > want to OR with 0 not ~0. My bad, I must have been thinking AND instead > of OR. > > I will change here as well as in Baolin's patch. Ah, I also overlooked this. Thanks Peter, and thanks Mike for updating. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-18 3:27 ` Baolin Wang 0 siblings, 0 replies; 57+ messages in thread From: Baolin Wang @ 2022-06-18 3:27 UTC (permalink / raw) To: Mike Kravetz, Peter Xu Cc: Michal Hocko, linux-ia64, linux-sh, catalin.marinas, Muchun Song, linux-mips, linux-mm, James Houghton, sparclinux, will, Mina Almasry, linux-s390, Christian Borntraeger, Anshuman Khandual, Paul Walmsley, Naoya Horiguchi, linux-arm-kernel, linux-parisc, linux-kernel, Aneesh Kumar K . V, Andrew Morton, linuxppc-dev On 6/18/2022 1:17 AM, Mike Kravetz wrote: > On 06/17/22 10:15, Peter Xu wrote: >> Hi, Mike, >> >> On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: >>> @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, >>> return (pte_t *)pmd; >>> } >>> >>> +/* >>> + * Return a mask that can be used to update an address to the last huge >>> + * page in a page table page mapping size. Used to skip non-present >>> + * page table entries when linearly scanning address ranges. Architectures >>> + * with unique huge page to page table relationships can define their own >>> + * version of this routine. >>> + */ >>> +unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + unsigned long hp_size = huge_page_size(h); >>> + >>> + switch (hp_size) { >>> + case P4D_SIZE: >>> + return PGDIR_SIZE - P4D_SIZE; >>> + case PUD_SIZE: >>> + return P4D_SIZE - PUD_SIZE; >>> + case PMD_SIZE: >>> + return PUD_SIZE - PMD_SIZE; >>> + default: >> >> Should we add a WARN_ON_ONCE() if it should never trigger? >> > > Sure. I will add this. > >>> + break; /* Should never happen */ >>> + } >>> + >>> + return ~(0UL); >>> +} >>> + >>> +#else >>> + >>> +/* See description above. Architectures can provide their own version. */ >>> +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + return ~(0UL); >> >> I'm wondering whether it's better to return 0 rather than ~0 by default. >> Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some >> valid address ranges with ~0, or perhaps I misread? > > Thank you, thank you, thank you Peter! > > Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If > there is no 'optimization', we do not want to modify the address so we > want to OR with 0 not ~0. My bad, I must have been thinking AND instead > of OR. > > I will change here as well as in Baolin's patch. Ah, I also overlooked this. Thanks Peter, and thanks Mike for updating. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-18 3:27 ` Baolin Wang 0 siblings, 0 replies; 57+ messages in thread From: Baolin Wang @ 2022-06-18 3:27 UTC (permalink / raw) To: Mike Kravetz, Peter Xu Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Muchun Song, Michal Hocko, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On 6/18/2022 1:17 AM, Mike Kravetz wrote: > On 06/17/22 10:15, Peter Xu wrote: >> Hi, Mike, >> >> On Thu, Jun 16, 2022 at 02:05:15PM -0700, Mike Kravetz wrote: >>> @@ -6877,6 +6896,39 @@ pte_t *huge_pte_offset(struct mm_struct *mm, >>> return (pte_t *)pmd; >>> } >>> >>> +/* >>> + * Return a mask that can be used to update an address to the last huge >>> + * page in a page table page mapping size. Used to skip non-present >>> + * page table entries when linearly scanning address ranges. Architectures >>> + * with unique huge page to page table relationships can define their own >>> + * version of this routine. >>> + */ >>> +unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + unsigned long hp_size = huge_page_size(h); >>> + >>> + switch (hp_size) { >>> + case P4D_SIZE: >>> + return PGDIR_SIZE - P4D_SIZE; >>> + case PUD_SIZE: >>> + return P4D_SIZE - PUD_SIZE; >>> + case PMD_SIZE: >>> + return PUD_SIZE - PMD_SIZE; >>> + default: >> >> Should we add a WARN_ON_ONCE() if it should never trigger? >> > > Sure. I will add this. > >>> + break; /* Should never happen */ >>> + } >>> + >>> + return ~(0UL); >>> +} >>> + >>> +#else >>> + >>> +/* See description above. Architectures can provide their own version. */ >>> +__weak unsigned long hugetlb_mask_last_page(struct hstate *h) >>> +{ >>> + return ~(0UL); >> >> I'm wondering whether it's better to return 0 rather than ~0 by default. >> Could an arch with !CONFIG_ARCH_WANT_GENERAL_HUGETLB wrongly skip some >> valid address ranges with ~0, or perhaps I misread? > > Thank you, thank you, thank you Peter! > > Yes, the 'default' return for hugetlb_mask_last_page() should be 0. If > there is no 'optimization', we do not want to modify the address so we > want to OR with 0 not ~0. My bad, I must have been thinking AND instead > of OR. > > I will change here as well as in Baolin's patch. Ah, I also overlooked this. Thanks Peter, and thanks Mike for updating. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-17 17:06 ` kernel test robot -1 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 17:06 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Linux Memory Management List, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-debian-10.3 (https://download.01.org/0day-ci/archive/20220618/202206180021.rcc4B1by-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): mm/hugetlb.c: In function 'hugetlb_mask_last_page': >> mm/hugetlb.c:6901:9: error: duplicate case value 6901 | case PUD_SIZE: | ^~~~ mm/hugetlb.c:6899:9: note: previously used here 6899 | case P4D_SIZE: | ^~~~ vim +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 17:06 ` kernel test robot 0 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 17:06 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Linux Memory Management List, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-debian-10.3 (https://download.01.org/0day-ci/archive/20220618/202206180021.rcc4B1by-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): mm/hugetlb.c: In function 'hugetlb_mask_last_page': >> mm/hugetlb.c:6901:9: error: duplicate case value 6901 | case PUD_SIZE: | ^~~~ mm/hugetlb.c:6899:9: note: previously used here 6899 | case P4D_SIZE: | ^~~~ vim +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 17:06 ` kernel test robot 0 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 17:06 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Mina Almasry, Michal Hocko, kbuild-all, will, Anshuman Khandual, catalin.marinas, Paul Walmsley, Peter Xu, Linux Memory Management List, James Houghton, Aneesh Kumar K . V, Baolin Wang, Muchun Song, Andrew Morton, Christian Borntraeger, Naoya Horiguchi, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-debian-10.3 (https://download.01.org/0day-ci/archive/20220618/202206180021.rcc4B1by-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): mm/hugetlb.c: In function 'hugetlb_mask_last_page': >> mm/hugetlb.c:6901:9: error: duplicate case value 6901 | case PUD_SIZE: | ^~~~ mm/hugetlb.c:6899:9: note: previously used here 6899 | case P4D_SIZE: | ^~~~ vim +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present @ 2022-06-17 17:06 ` kernel test robot 0 siblings, 0 replies; 57+ messages in thread From: kernel test robot @ 2022-06-17 17:06 UTC (permalink / raw) To: Mike Kravetz, linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: kbuild-all, Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on linus/master v5.19-rc2 next-20220617] [cannot apply to arm64/for-next/core arm/for-next kvmarm/next xilinx-xlnx/master] [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] url: https://github.com/intel-lab-lkp/linux/commits/Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: i386-debian-10.3 (https://download.01.org/0day-ci/archive/20220618/202206180021.rcc4B1by-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/4c647687607f10fece04967b8180c0dadaf765e6 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Mike-Kravetz/hugetlb-speed-up-linear-address-scanning/20220617-050726 git checkout 4c647687607f10fece04967b8180c0dadaf765e6 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): mm/hugetlb.c: In function 'hugetlb_mask_last_page': >> mm/hugetlb.c:6901:9: error: duplicate case value 6901 | case PUD_SIZE: | ^~~~ mm/hugetlb.c:6899:9: note: previously used here 6899 | case P4D_SIZE: | ^~~~ vim +6901 mm/hugetlb.c 6886 6887 /* 6888 * Return a mask that can be used to update an address to the last huge 6889 * page in a page table page mapping size. Used to skip non-present 6890 * page table entries when linearly scanning address ranges. Architectures 6891 * with unique huge page to page table relationships can define their own 6892 * version of this routine. 6893 */ 6894 unsigned long hugetlb_mask_last_page(struct hstate *h) 6895 { 6896 unsigned long hp_size = huge_page_size(h); 6897 6898 switch (hp_size) { 6899 case P4D_SIZE: 6900 return PGDIR_SIZE - P4D_SIZE; > 6901 case PUD_SIZE: 6902 return P4D_SIZE - PUD_SIZE; 6903 case PMD_SIZE: 6904 return PUD_SIZE - PMD_SIZE; 6905 default: 6906 break; /* Should never happen */ 6907 } 6908 6909 return ~(0UL); 6910 } 6911 -- 0-DAY CI Kernel Test Service https://01.org/lkp ^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-16 21:05 ` Mike Kravetz -1 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz From: Baolin Wang <baolin.wang@linux.alibaba.com> The HugeTLB address ranges are linearly scanned during fork, unmap and remap operations, and the linear scan can skip to the end of range mapped by the page table page if hitting a non-present entry, which can help to speed linear scanning of the HugeTLB address ranges. So hugetlb_mask_last_page() is introduced to help to update the address in the loop of HugeTLB linear scanning with getting the last huge page mapped by the associated page table page[1], when a non-present entry is encountered. Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented an ARM64 specific hugetlb_mask_last_page() to help this case. [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> --- arch/arm64/mm/hugetlbpage.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index e2a5ec9fdc0d..ddeafee7c4de 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -368,6 +368,26 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return NULL; } +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case PUD_SIZE: + return PGDIR_SIZE - PUD_SIZE; + case CONT_PMD_SIZE: + return PUD_SIZE - CONT_PMD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + case CONT_PTE_SIZE: + return PMD_SIZE - CONT_PTE_SIZE; + default: + break; + } + + return ~0UL; +} + pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) { size_t pagesize = 1UL << shift; -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz From: Baolin Wang <baolin.wang@linux.alibaba.com> The HugeTLB address ranges are linearly scanned during fork, unmap and remap operations, and the linear scan can skip to the end of range mapped by the page table page if hitting a non-present entry, which can help to speed linear scanning of the HugeTLB address ranges. So hugetlb_mask_last_page() is introduced to help to update the address in the loop of HugeTLB linear scanning with getting the last huge page mapped by the associated page table page[1], when a non-present entry is encountered. Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented an ARM64 specific hugetlb_mask_last_page() to help this case. [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> --- arch/arm64/mm/hugetlbpage.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index e2a5ec9fdc0d..ddeafee7c4de 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -368,6 +368,26 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return NULL; } +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case PUD_SIZE: + return PGDIR_SIZE - PUD_SIZE; + case CONT_PMD_SIZE: + return PUD_SIZE - CONT_PMD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + case CONT_PTE_SIZE: + return PMD_SIZE - CONT_PTE_SIZE; + default: + break; + } + + return ~0UL; +} + pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) { size_t pagesize = 1UL << shift; -- 2.35.3 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Mina Almasry, James Houghton, will, Anshuman Khandual, catalin.marinas, Paul Walmsley, Peter Xu, Michal Hocko, Aneesh Kumar K . V, Baolin Wang, Muchun Song, Andrew Morton, Christian Borntraeger, Naoya Horiguchi, Mike Kravetz From: Baolin Wang <baolin.wang@linux.alibaba.com> The HugeTLB address ranges are linearly scanned during fork, unmap and remap operations, and the linear scan can skip to the end of range mapped by the page table page if hitting a non-present entry, which can help to speed linear scanning of the HugeTLB address ranges. So hugetlb_mask_last_page() is introduced to help to update the address in the loop of HugeTLB linear scanning with getting the last huge page mapped by the associated page table page[1], when a non-present entry is encountered. Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented an ARM64 specific hugetlb_mask_last_page() to help this case. [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> --- arch/arm64/mm/hugetlbpage.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index e2a5ec9fdc0d..ddeafee7c4de 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -368,6 +368,26 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return NULL; } +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case PUD_SIZE: + return PGDIR_SIZE - PUD_SIZE; + case CONT_PMD_SIZE: + return PUD_SIZE - CONT_PMD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + case CONT_PTE_SIZE: + return PMD_SIZE - CONT_PTE_SIZE; + default: + break; + } + + return ~0UL; +} + pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) { size_t pagesize = 1UL << shift; -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz From: Baolin Wang <baolin.wang@linux.alibaba.com> The HugeTLB address ranges are linearly scanned during fork, unmap and remap operations, and the linear scan can skip to the end of range mapped by the page table page if hitting a non-present entry, which can help to speed linear scanning of the HugeTLB address ranges. So hugetlb_mask_last_page() is introduced to help to update the address in the loop of HugeTLB linear scanning with getting the last huge page mapped by the associated page table page[1], when a non-present entry is encountered. Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented an ARM64 specific hugetlb_mask_last_page() to help this case. [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> --- arch/arm64/mm/hugetlbpage.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index e2a5ec9fdc0d..ddeafee7c4de 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -368,6 +368,26 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return NULL; } +unsigned long hugetlb_mask_last_page(struct hstate *h) +{ + unsigned long hp_size = huge_page_size(h); + + switch (hp_size) { + case PUD_SIZE: + return PGDIR_SIZE - PUD_SIZE; + case CONT_PMD_SIZE: + return PUD_SIZE - CONT_PMD_SIZE; + case PMD_SIZE: + return PUD_SIZE - PMD_SIZE; + case CONT_PTE_SIZE: + return PMD_SIZE - CONT_PTE_SIZE; + default: + break; + } + + return ~0UL; +} + pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) { size_t pagesize = 1UL << shift; -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* Re: [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-17 8:26 ` Muchun Song -1 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:26 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On Thu, Jun 16, 2022 at 02:05:16PM -0700, Mike Kravetz wrote: > From: Baolin Wang <baolin.wang@linux.alibaba.com> > > The HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations, and the linear scan can skip to the end of range mapped > by the page table page if hitting a non-present entry, which can help > to speed linear scanning of the HugeTLB address ranges. > > So hugetlb_mask_last_page() is introduced to help to update the address in > the loop of HugeTLB linear scanning with getting the last huge page mapped > by the associated page table page[1], when a non-present entry is encountered. > > Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented > an ARM64 specific hugetlb_mask_last_page() to help this case. > > [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ > > Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Thanks. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page @ 2022-06-17 8:26 ` Muchun Song 0 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:26 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On Thu, Jun 16, 2022 at 02:05:16PM -0700, Mike Kravetz wrote: > From: Baolin Wang <baolin.wang@linux.alibaba.com> > > The HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations, and the linear scan can skip to the end of range mapped > by the page table page if hitting a non-present entry, which can help > to speed linear scanning of the HugeTLB address ranges. > > So hugetlb_mask_last_page() is introduced to help to update the address in > the loop of HugeTLB linear scanning with getting the last huge page mapped > by the associated page table page[1], when a non-present entry is encountered. > > Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented > an ARM64 specific hugetlb_mask_last_page() to help this case. > > [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ > > Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Thanks. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page @ 2022-06-17 8:26 ` Muchun Song 0 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:26 UTC (permalink / raw) To: Mike Kravetz Cc: Michal Hocko, linux-ia64, linux-sh, catalin.marinas, Peter Xu, linux-mips, linux-mm, James Houghton, sparclinux, will, Mina Almasry, linux-s390, Christian Borntraeger, Anshuman Khandual, Baolin Wang, Paul Walmsley, Naoya Horiguchi, linux-arm-kernel, linux-parisc, linux-kernel, Aneesh Kumar K . V, Andrew Morton, linuxppc-dev On Thu, Jun 16, 2022 at 02:05:16PM -0700, Mike Kravetz wrote: > From: Baolin Wang <baolin.wang@linux.alibaba.com> > > The HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations, and the linear scan can skip to the end of range mapped > by the page table page if hitting a non-present entry, which can help > to speed linear scanning of the HugeTLB address ranges. > > So hugetlb_mask_last_page() is introduced to help to update the address in > the loop of HugeTLB linear scanning with getting the last huge page mapped > by the associated page table page[1], when a non-present entry is encountered. > > Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented > an ARM64 specific hugetlb_mask_last_page() to help this case. > > [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ > > Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Thanks. ^ permalink raw reply [flat|nested] 57+ messages in thread
* Re: [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page @ 2022-06-17 8:26 ` Muchun Song 0 siblings, 0 replies; 57+ messages in thread From: Muchun Song @ 2022-06-17 8:26 UTC (permalink / raw) To: Mike Kravetz Cc: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton On Thu, Jun 16, 2022 at 02:05:16PM -0700, Mike Kravetz wrote: > From: Baolin Wang <baolin.wang@linux.alibaba.com> > > The HugeTLB address ranges are linearly scanned during fork, unmap and > remap operations, and the linear scan can skip to the end of range mapped > by the page table page if hitting a non-present entry, which can help > to speed linear scanning of the HugeTLB address ranges. > > So hugetlb_mask_last_page() is introduced to help to update the address in > the loop of HugeTLB linear scanning with getting the last huge page mapped > by the associated page table page[1], when a non-present entry is encountered. > > Considering ARM64 specific cont-pte/pmd size HugeTLB, this patch implemented > an ARM64 specific hugetlb_mask_last_page() to help this case. > > [1] https://lore.kernel.org/linux-mm/20220527225849.284839-1-mike.kravetz@oracle.com/ > > Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> > Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Thanks. ^ permalink raw reply [flat|nested] 57+ messages in thread
* [PATCH 3/4] hugetlb: do not update address in huge_pmd_unshare 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-16 21:05 ` Mike Kravetz -1 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz As an optimization for loops sequentially processing hugetlb address ranges, huge_pmd_unshare would update a passed address if it unshared a pmd. Updating a loop control variable outside the loop like this is generally a bad idea. These loops are now using hugetlb_mask_last_page to optimize scanning when non-present ptes are discovered. The same can be done when huge_pmd_unshare returns 1 indicating a pmd was unshared. Remove address update from huge_pmd_unshare. Change the passed argument type and update all callers. In loops sequentially processing addresses use hugetlb_mask_last_page to update address if pmd is unshared. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 4 ++-- mm/hugetlb.c | 47 ++++++++++++++++++----------------------- mm/rmap.c | 4 ++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index e37465e830fe..ee9a28ef26ee 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -199,7 +199,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep); + unsigned long addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, unsigned long *start, unsigned long *end); struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, @@ -246,7 +246,7 @@ static inline struct address_space *hugetlb_page_mapping_lock_write( static inline int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7c4a82848603..f7da2d54ef39 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4949,7 +4949,6 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; unsigned long last_addr_mask; - unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; bool shared_pmd = false; @@ -4977,14 +4976,10 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, if (huge_pte_none(huge_ptep_get(src_pte))) continue; - /* old_addr arg to huge_pmd_unshare() is a pointer and so the - * arg may be modified. Pass a copy instead to preserve the - * value in old_addr. - */ - old_addr_copy = old_addr; - - if (huge_pmd_unshare(mm, vma, &old_addr_copy, src_pte)) { + if (huge_pmd_unshare(mm, vma, old_addr, src_pte)) { shared_pmd = true; + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; } @@ -5049,10 +5044,11 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { spin_unlock(ptl); tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE); force_flush = true; + address |= last_addr_mask; continue; } @@ -6347,7 +6343,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, continue; } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { /* * When uffd-wp is enabled on the vma, unshare * shouldn't happen at all. Warn about it if it @@ -6357,6 +6353,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, pages++; spin_unlock(ptl); shared_pmd = true; + address |= last_addr_mask; continue; } pte = huge_ptep_get(ptep); @@ -6780,11 +6777,11 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, * 0 the underlying pte page is not shared, or it is the last user */ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { - pgd_t *pgd = pgd_offset(mm, *addr); - p4d_t *p4d = p4d_offset(pgd, *addr); - pud_t *pud = pud_offset(p4d, *addr); + pgd_t *pgd = pgd_offset(mm, addr); + p4d_t *p4d = p4d_offset(pgd, addr); + pud_t *pud = pud_offset(p4d, addr); i_mmap_assert_write_locked(vma->vm_file->f_mapping); BUG_ON(page_count(virt_to_page(ptep)) == 0); @@ -6794,14 +6791,6 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, pud_clear(pud); put_page(virt_to_page(ptep)); mm_dec_nr_pmds(mm); - /* - * This update of passed address optimizes loops sequentially - * processing addresses in increments of huge page size (PMD_SIZE - * in this case). By clearing the pud, a PUD_SIZE area is unmapped. - * Update address to the 'last page' in the cleared area so that - * calling loop can move to first page past this area. - */ - *addr |= PUD_SIZE - PMD_SIZE; return 1; } @@ -6813,7 +6802,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, } int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } @@ -6926,6 +6915,13 @@ unsigned long hugetlb_mask_last_page(struct hstate *h) /* See description above. Architectures can provide their own version. */ __weak unsigned long hugetlb_mask_last_page(struct hstate *h) { + unsigned long hp_size = huge_page_size(h); + +#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE + /* Required if arch does pmd sharing */ + if (hp_size == PMD_SIZE) + return PUD_SIZE - PMD_SIZE; +#endif return ~(0UL); } @@ -7152,14 +7148,11 @@ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) mmu_notifier_invalidate_range_start(&range); i_mmap_lock_write(vma->vm_file->f_mapping); for (address = start; address < end; address += PUD_SIZE) { - unsigned long tmp = address; - ptep = huge_pte_offset(mm, address, sz); if (!ptep) continue; ptl = huge_pte_lock(h, mm, ptep); - /* We don't want 'address' to be changed */ - huge_pmd_unshare(mm, vma, &tmp, ptep); + huge_pmd_unshare(mm, vma, address, ptep); spin_unlock(ptl); } flush_hugetlb_tlb_range(vma, start, end); diff --git a/mm/rmap.c b/mm/rmap.c index 04fac1af870b..1c22e5e1219a 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1559,7 +1559,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); @@ -1923,7 +1923,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 3/4] hugetlb: do not update address in huge_pmd_unshare @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz As an optimization for loops sequentially processing hugetlb address ranges, huge_pmd_unshare would update a passed address if it unshared a pmd. Updating a loop control variable outside the loop like this is generally a bad idea. These loops are now using hugetlb_mask_last_page to optimize scanning when non-present ptes are discovered. The same can be done when huge_pmd_unshare returns 1 indicating a pmd was unshared. Remove address update from huge_pmd_unshare. Change the passed argument type and update all callers. In loops sequentially processing addresses use hugetlb_mask_last_page to update address if pmd is unshared. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 4 ++-- mm/hugetlb.c | 47 ++++++++++++++++++----------------------- mm/rmap.c | 4 ++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index e37465e830fe..ee9a28ef26ee 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -199,7 +199,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep); + unsigned long addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, unsigned long *start, unsigned long *end); struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, @@ -246,7 +246,7 @@ static inline struct address_space *hugetlb_page_mapping_lock_write( static inline int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7c4a82848603..f7da2d54ef39 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4949,7 +4949,6 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; unsigned long last_addr_mask; - unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; bool shared_pmd = false; @@ -4977,14 +4976,10 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, if (huge_pte_none(huge_ptep_get(src_pte))) continue; - /* old_addr arg to huge_pmd_unshare() is a pointer and so the - * arg may be modified. Pass a copy instead to preserve the - * value in old_addr. - */ - old_addr_copy = old_addr; - - if (huge_pmd_unshare(mm, vma, &old_addr_copy, src_pte)) { + if (huge_pmd_unshare(mm, vma, old_addr, src_pte)) { shared_pmd = true; + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; } @@ -5049,10 +5044,11 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { spin_unlock(ptl); tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE); force_flush = true; + address |= last_addr_mask; continue; } @@ -6347,7 +6343,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, continue; } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { /* * When uffd-wp is enabled on the vma, unshare * shouldn't happen at all. Warn about it if it @@ -6357,6 +6353,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, pages++; spin_unlock(ptl); shared_pmd = true; + address |= last_addr_mask; continue; } pte = huge_ptep_get(ptep); @@ -6780,11 +6777,11 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, * 0 the underlying pte page is not shared, or it is the last user */ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { - pgd_t *pgd = pgd_offset(mm, *addr); - p4d_t *p4d = p4d_offset(pgd, *addr); - pud_t *pud = pud_offset(p4d, *addr); + pgd_t *pgd = pgd_offset(mm, addr); + p4d_t *p4d = p4d_offset(pgd, addr); + pud_t *pud = pud_offset(p4d, addr); i_mmap_assert_write_locked(vma->vm_file->f_mapping); BUG_ON(page_count(virt_to_page(ptep)) == 0); @@ -6794,14 +6791,6 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, pud_clear(pud); put_page(virt_to_page(ptep)); mm_dec_nr_pmds(mm); - /* - * This update of passed address optimizes loops sequentially - * processing addresses in increments of huge page size (PMD_SIZE - * in this case). By clearing the pud, a PUD_SIZE area is unmapped. - * Update address to the 'last page' in the cleared area so that - * calling loop can move to first page past this area. - */ - *addr |= PUD_SIZE - PMD_SIZE; return 1; } @@ -6813,7 +6802,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, } int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } @@ -6926,6 +6915,13 @@ unsigned long hugetlb_mask_last_page(struct hstate *h) /* See description above. Architectures can provide their own version. */ __weak unsigned long hugetlb_mask_last_page(struct hstate *h) { + unsigned long hp_size = huge_page_size(h); + +#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE + /* Required if arch does pmd sharing */ + if (hp_size == PMD_SIZE) + return PUD_SIZE - PMD_SIZE; +#endif return ~(0UL); } @@ -7152,14 +7148,11 @@ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) mmu_notifier_invalidate_range_start(&range); i_mmap_lock_write(vma->vm_file->f_mapping); for (address = start; address < end; address += PUD_SIZE) { - unsigned long tmp = address; - ptep = huge_pte_offset(mm, address, sz); if (!ptep) continue; ptl = huge_pte_lock(h, mm, ptep); - /* We don't want 'address' to be changed */ - huge_pmd_unshare(mm, vma, &tmp, ptep); + huge_pmd_unshare(mm, vma, address, ptep); spin_unlock(ptl); } flush_hugetlb_tlb_range(vma, start, end); diff --git a/mm/rmap.c b/mm/rmap.c index 04fac1af870b..1c22e5e1219a 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1559,7 +1559,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); @@ -1923,7 +1923,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); -- 2.35.3 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 3/4] hugetlb: do not update address in huge_pmd_unshare @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Mina Almasry, James Houghton, will, Anshuman Khandual, catalin.marinas, Paul Walmsley, Peter Xu, Michal Hocko, Aneesh Kumar K . V, Baolin Wang, Muchun Song, Andrew Morton, Christian Borntraeger, Naoya Horiguchi, Mike Kravetz As an optimization for loops sequentially processing hugetlb address ranges, huge_pmd_unshare would update a passed address if it unshared a pmd. Updating a loop control variable outside the loop like this is generally a bad idea. These loops are now using hugetlb_mask_last_page to optimize scanning when non-present ptes are discovered. The same can be done when huge_pmd_unshare returns 1 indicating a pmd was unshared. Remove address update from huge_pmd_unshare. Change the passed argument type and update all callers. In loops sequentially processing addresses use hugetlb_mask_last_page to update address if pmd is unshared. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 4 ++-- mm/hugetlb.c | 47 ++++++++++++++++++----------------------- mm/rmap.c | 4 ++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index e37465e830fe..ee9a28ef26ee 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -199,7 +199,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep); + unsigned long addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, unsigned long *start, unsigned long *end); struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, @@ -246,7 +246,7 @@ static inline struct address_space *hugetlb_page_mapping_lock_write( static inline int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7c4a82848603..f7da2d54ef39 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4949,7 +4949,6 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; unsigned long last_addr_mask; - unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; bool shared_pmd = false; @@ -4977,14 +4976,10 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, if (huge_pte_none(huge_ptep_get(src_pte))) continue; - /* old_addr arg to huge_pmd_unshare() is a pointer and so the - * arg may be modified. Pass a copy instead to preserve the - * value in old_addr. - */ - old_addr_copy = old_addr; - - if (huge_pmd_unshare(mm, vma, &old_addr_copy, src_pte)) { + if (huge_pmd_unshare(mm, vma, old_addr, src_pte)) { shared_pmd = true; + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; } @@ -5049,10 +5044,11 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { spin_unlock(ptl); tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE); force_flush = true; + address |= last_addr_mask; continue; } @@ -6347,7 +6343,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, continue; } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { /* * When uffd-wp is enabled on the vma, unshare * shouldn't happen at all. Warn about it if it @@ -6357,6 +6353,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, pages++; spin_unlock(ptl); shared_pmd = true; + address |= last_addr_mask; continue; } pte = huge_ptep_get(ptep); @@ -6780,11 +6777,11 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, * 0 the underlying pte page is not shared, or it is the last user */ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { - pgd_t *pgd = pgd_offset(mm, *addr); - p4d_t *p4d = p4d_offset(pgd, *addr); - pud_t *pud = pud_offset(p4d, *addr); + pgd_t *pgd = pgd_offset(mm, addr); + p4d_t *p4d = p4d_offset(pgd, addr); + pud_t *pud = pud_offset(p4d, addr); i_mmap_assert_write_locked(vma->vm_file->f_mapping); BUG_ON(page_count(virt_to_page(ptep)) == 0); @@ -6794,14 +6791,6 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, pud_clear(pud); put_page(virt_to_page(ptep)); mm_dec_nr_pmds(mm); - /* - * This update of passed address optimizes loops sequentially - * processing addresses in increments of huge page size (PMD_SIZE - * in this case). By clearing the pud, a PUD_SIZE area is unmapped. - * Update address to the 'last page' in the cleared area so that - * calling loop can move to first page past this area. - */ - *addr |= PUD_SIZE - PMD_SIZE; return 1; } @@ -6813,7 +6802,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, } int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } @@ -6926,6 +6915,13 @@ unsigned long hugetlb_mask_last_page(struct hstate *h) /* See description above. Architectures can provide their own version. */ __weak unsigned long hugetlb_mask_last_page(struct hstate *h) { + unsigned long hp_size = huge_page_size(h); + +#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE + /* Required if arch does pmd sharing */ + if (hp_size == PMD_SIZE) + return PUD_SIZE - PMD_SIZE; +#endif return ~(0UL); } @@ -7152,14 +7148,11 @@ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) mmu_notifier_invalidate_range_start(&range); i_mmap_lock_write(vma->vm_file->f_mapping); for (address = start; address < end; address += PUD_SIZE) { - unsigned long tmp = address; - ptep = huge_pte_offset(mm, address, sz); if (!ptep) continue; ptl = huge_pte_lock(h, mm, ptep); - /* We don't want 'address' to be changed */ - huge_pmd_unshare(mm, vma, &tmp, ptep); + huge_pmd_unshare(mm, vma, address, ptep); spin_unlock(ptl); } flush_hugetlb_tlb_range(vma, start, end); diff --git a/mm/rmap.c b/mm/rmap.c index 04fac1af870b..1c22e5e1219a 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1559,7 +1559,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); @@ -1923,7 +1923,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 3/4] hugetlb: do not update address in huge_pmd_unshare @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz As an optimization for loops sequentially processing hugetlb address ranges, huge_pmd_unshare would update a passed address if it unshared a pmd. Updating a loop control variable outside the loop like this is generally a bad idea. These loops are now using hugetlb_mask_last_page to optimize scanning when non-present ptes are discovered. The same can be done when huge_pmd_unshare returns 1 indicating a pmd was unshared. Remove address update from huge_pmd_unshare. Change the passed argument type and update all callers. In loops sequentially processing addresses use hugetlb_mask_last_page to update address if pmd is unshared. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> --- include/linux/hugetlb.h | 4 ++-- mm/hugetlb.c | 47 ++++++++++++++++++----------------------- mm/rmap.c | 4 ++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index e37465e830fe..ee9a28ef26ee 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -199,7 +199,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz); unsigned long hugetlb_mask_last_page(struct hstate *h); int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep); + unsigned long addr, pte_t *ptep); void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, unsigned long *start, unsigned long *end); struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, @@ -246,7 +246,7 @@ static inline struct address_space *hugetlb_page_mapping_lock_write( static inline int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7c4a82848603..f7da2d54ef39 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4949,7 +4949,6 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, struct mm_struct *mm = vma->vm_mm; unsigned long old_end = old_addr + len; unsigned long last_addr_mask; - unsigned long old_addr_copy; pte_t *src_pte, *dst_pte; struct mmu_notifier_range range; bool shared_pmd = false; @@ -4977,14 +4976,10 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma, if (huge_pte_none(huge_ptep_get(src_pte))) continue; - /* old_addr arg to huge_pmd_unshare() is a pointer and so the - * arg may be modified. Pass a copy instead to preserve the - * value in old_addr. - */ - old_addr_copy = old_addr; - - if (huge_pmd_unshare(mm, vma, &old_addr_copy, src_pte)) { + if (huge_pmd_unshare(mm, vma, old_addr, src_pte)) { shared_pmd = true; + old_addr |= last_addr_mask; + new_addr |= last_addr_mask; continue; } @@ -5049,10 +5044,11 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { spin_unlock(ptl); tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE); force_flush = true; + address |= last_addr_mask; continue; } @@ -6347,7 +6343,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, continue; } ptl = huge_pte_lock(h, mm, ptep); - if (huge_pmd_unshare(mm, vma, &address, ptep)) { + if (huge_pmd_unshare(mm, vma, address, ptep)) { /* * When uffd-wp is enabled on the vma, unshare * shouldn't happen at all. Warn about it if it @@ -6357,6 +6353,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, pages++; spin_unlock(ptl); shared_pmd = true; + address |= last_addr_mask; continue; } pte = huge_ptep_get(ptep); @@ -6780,11 +6777,11 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, * 0 the underlying pte page is not shared, or it is the last user */ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { - pgd_t *pgd = pgd_offset(mm, *addr); - p4d_t *p4d = p4d_offset(pgd, *addr); - pud_t *pud = pud_offset(p4d, *addr); + pgd_t *pgd = pgd_offset(mm, addr); + p4d_t *p4d = p4d_offset(pgd, addr); + pud_t *pud = pud_offset(p4d, addr); i_mmap_assert_write_locked(vma->vm_file->f_mapping); BUG_ON(page_count(virt_to_page(ptep)) = 0); @@ -6794,14 +6791,6 @@ int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, pud_clear(pud); put_page(virt_to_page(ptep)); mm_dec_nr_pmds(mm); - /* - * This update of passed address optimizes loops sequentially - * processing addresses in increments of huge page size (PMD_SIZE - * in this case). By clearing the pud, a PUD_SIZE area is unmapped. - * Update address to the 'last page' in the cleared area so that - * calling loop can move to first page past this area. - */ - *addr |= PUD_SIZE - PMD_SIZE; return 1; } @@ -6813,7 +6802,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma, } int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long *addr, pte_t *ptep) + unsigned long addr, pte_t *ptep) { return 0; } @@ -6926,6 +6915,13 @@ unsigned long hugetlb_mask_last_page(struct hstate *h) /* See description above. Architectures can provide their own version. */ __weak unsigned long hugetlb_mask_last_page(struct hstate *h) { + unsigned long hp_size = huge_page_size(h); + +#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE + /* Required if arch does pmd sharing */ + if (hp_size = PMD_SIZE) + return PUD_SIZE - PMD_SIZE; +#endif return ~(0UL); } @@ -7152,14 +7148,11 @@ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) mmu_notifier_invalidate_range_start(&range); i_mmap_lock_write(vma->vm_file->f_mapping); for (address = start; address < end; address += PUD_SIZE) { - unsigned long tmp = address; - ptep = huge_pte_offset(mm, address, sz); if (!ptep) continue; ptl = huge_pte_lock(h, mm, ptep); - /* We don't want 'address' to be changed */ - huge_pmd_unshare(mm, vma, &tmp, ptep); + huge_pmd_unshare(mm, vma, address, ptep); spin_unlock(ptl); } flush_hugetlb_tlb_range(vma, start, end); diff --git a/mm/rmap.c b/mm/rmap.c index 04fac1af870b..1c22e5e1219a 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1559,7 +1559,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); @@ -1923,7 +1923,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, */ VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (huge_pmd_unshare(mm, vma, &address, pvmw.pte)) { + if (huge_pmd_unshare(mm, vma, address, pvmw.pte)) { flush_tlb_range(vma, range.start, range.end); mmu_notifier_invalidate_range(mm, range.start, range.end); -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 4/4] hugetlb: Lazy page table copies in fork() 2022-06-16 21:05 ` Mike Kravetz (?) (?) @ 2022-06-16 21:05 ` Mike Kravetz -1 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz, David Hildenbrand Lazy page table copying at fork time was introduced with commit commit d992895ba2b2 ("[PATCH] Lazy page table copies in fork()"). At the time, hugetlb was very new and did not support page faulting. As a result, it was excluded. When full page fault support was added for hugetlb, the exclusion was not removed. Simply remove the check that prevents lazy copying of hugetlb page tables at fork. Of course, like other mappings this only applies to shared mappings. Lazy page table copying at fork will be less advantageous for hugetlb mappings because: - There are fewer page table entries with hugetlb - hugetlb pmds can be shared instead of copied In any case, completely eliminating the copy at fork time should speed things up. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Acked-by: David Hildenbrand <david@redhat.com> --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index fee2884481f2..90d2a614b2de 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1262,7 +1262,7 @@ vma_needs_copy(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) if (userfaultfd_wp(dst_vma)) return true; - if (src_vma->vm_flags & (VM_HUGETLB | VM_PFNMAP | VM_MIXEDMAP)) + if (src_vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) return true; if (src_vma->anon_vma) -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 4/4] hugetlb: Lazy page table copies in fork() @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz, David Hildenbrand Lazy page table copying at fork time was introduced with commit commit d992895ba2b2 ("[PATCH] Lazy page table copies in fork()"). At the time, hugetlb was very new and did not support page faulting. As a result, it was excluded. When full page fault support was added for hugetlb, the exclusion was not removed. Simply remove the check that prevents lazy copying of hugetlb page tables at fork. Of course, like other mappings this only applies to shared mappings. Lazy page table copying at fork will be less advantageous for hugetlb mappings because: - There are fewer page table entries with hugetlb - hugetlb pmds can be shared instead of copied In any case, completely eliminating the copy at fork time should speed things up. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Acked-by: David Hildenbrand <david@redhat.com> --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index fee2884481f2..90d2a614b2de 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1262,7 +1262,7 @@ vma_needs_copy(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) if (userfaultfd_wp(dst_vma)) return true; - if (src_vma->vm_flags & (VM_HUGETLB | VM_PFNMAP | VM_MIXEDMAP)) + if (src_vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) return true; if (src_vma->anon_vma) -- 2.35.3 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 4/4] hugetlb: Lazy page table copies in fork() @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Mina Almasry, James Houghton, will, Anshuman Khandual, catalin.marinas, Paul Walmsley, David Hildenbrand, Peter Xu, Michal Hocko, Aneesh Kumar K . V, Baolin Wang, Muchun Song, Andrew Morton, Christian Borntraeger, Naoya Horiguchi, Mike Kravetz Lazy page table copying at fork time was introduced with commit commit d992895ba2b2 ("[PATCH] Lazy page table copies in fork()"). At the time, hugetlb was very new and did not support page faulting. As a result, it was excluded. When full page fault support was added for hugetlb, the exclusion was not removed. Simply remove the check that prevents lazy copying of hugetlb page tables at fork. Of course, like other mappings this only applies to shared mappings. Lazy page table copying at fork will be less advantageous for hugetlb mappings because: - There are fewer page table entries with hugetlb - hugetlb pmds can be shared instead of copied In any case, completely eliminating the copy at fork time should speed things up. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Acked-by: David Hildenbrand <david@redhat.com> --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index fee2884481f2..90d2a614b2de 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1262,7 +1262,7 @@ vma_needs_copy(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) if (userfaultfd_wp(dst_vma)) return true; - if (src_vma->vm_flags & (VM_HUGETLB | VM_PFNMAP | VM_MIXEDMAP)) + if (src_vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) return true; if (src_vma->anon_vma) -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
* [PATCH 4/4] hugetlb: Lazy page table copies in fork() @ 2022-06-16 21:05 ` Mike Kravetz 0 siblings, 0 replies; 57+ messages in thread From: Mike Kravetz @ 2022-06-16 21:05 UTC (permalink / raw) To: linux-kernel, linux-mm, linux-arm-kernel, linux-s390, linux-sh, sparclinux, linux-ia64, linux-mips, linux-parisc, linuxppc-dev Cc: Muchun Song, Baolin Wang, Michal Hocko, Peter Xu, Naoya Horiguchi, James Houghton, Mina Almasry, Aneesh Kumar K . V, Anshuman Khandual, Paul Walmsley, Christian Borntraeger, catalin.marinas, will, Andrew Morton, Mike Kravetz, David Hildenbrand Lazy page table copying at fork time was introduced with commit commit d992895ba2b2 ("[PATCH] Lazy page table copies in fork()"). At the time, hugetlb was very new and did not support page faulting. As a result, it was excluded. When full page fault support was added for hugetlb, the exclusion was not removed. Simply remove the check that prevents lazy copying of hugetlb page tables at fork. Of course, like other mappings this only applies to shared mappings. Lazy page table copying at fork will be less advantageous for hugetlb mappings because: - There are fewer page table entries with hugetlb - hugetlb pmds can be shared instead of copied In any case, completely eliminating the copy at fork time should speed things up. Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: Muchun Song <songmuchun@bytedance.com> Acked-by: David Hildenbrand <david@redhat.com> --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index fee2884481f2..90d2a614b2de 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1262,7 +1262,7 @@ vma_needs_copy(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) if (userfaultfd_wp(dst_vma)) return true; - if (src_vma->vm_flags & (VM_HUGETLB | VM_PFNMAP | VM_MIXEDMAP)) + if (src_vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) return true; if (src_vma->anon_vma) -- 2.35.3 ^ permalink raw reply related [flat|nested] 57+ messages in thread
end of thread, other threads:[~2022-06-18 3:33 UTC | newest] Thread overview: 57+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-06-16 21:05 [PATCH 0/4] hugetlb: speed up linear address scanning Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` [PATCH 1/4] hugetlb: skip to end of PT page mapping when pte not present Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-17 8:13 ` Muchun Song 2022-06-17 8:13 ` Muchun Song 2022-06-17 8:13 ` Muchun Song 2022-06-17 8:13 ` Muchun Song 2022-06-17 11:26 ` kernel test robot 2022-06-17 11:26 ` kernel test robot 2022-06-17 11:26 ` kernel test robot 2022-06-17 11:26 ` kernel test robot 2022-06-17 21:09 ` Mike Kravetz 2022-06-17 21:09 ` Mike Kravetz 2022-06-17 21:09 ` Mike Kravetz 2022-06-17 21:09 ` Mike Kravetz 2022-06-17 21:09 ` Mike Kravetz 2022-06-17 14:15 ` Peter Xu 2022-06-17 14:15 ` Peter Xu 2022-06-17 14:15 ` Peter Xu 2022-06-17 14:15 ` Peter Xu 2022-06-17 15:26 ` Geert Uytterhoeven 2022-06-17 15:26 ` Geert Uytterhoeven 2022-06-17 15:26 ` Geert Uytterhoeven 2022-06-17 15:26 ` Geert Uytterhoeven 2022-06-17 17:17 ` Mike Kravetz 2022-06-17 17:17 ` Mike Kravetz 2022-06-17 17:17 ` Mike Kravetz 2022-06-17 17:17 ` Mike Kravetz 2022-06-18 3:27 ` Baolin Wang 2022-06-18 3:27 ` Baolin Wang 2022-06-18 3:27 ` Baolin Wang 2022-06-18 3:27 ` Baolin Wang 2022-06-17 17:06 ` kernel test robot 2022-06-17 17:06 ` kernel test robot 2022-06-17 17:06 ` kernel test robot 2022-06-17 17:06 ` kernel test robot 2022-06-16 21:05 ` [PATCH 2/4] arm64/hugetlb: Implement arm64 specific hugetlb_mask_last_page Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-17 8:26 ` Muchun Song 2022-06-17 8:26 ` Muchun Song 2022-06-17 8:26 ` Muchun Song 2022-06-17 8:26 ` Muchun Song 2022-06-16 21:05 ` [PATCH 3/4] hugetlb: do not update address in huge_pmd_unshare Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` [PATCH 4/4] hugetlb: Lazy page table copies in fork() Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz 2022-06-16 21:05 ` Mike Kravetz
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.