From: "Barry Song (Xiaomi)" <[email protected]>

Allow arch_vmap_pte_range_map_size to batch across multiple CONT_PTE
blocks, reducing both PTE setup and TLB flush iterations.

For CONT_PTE_SIZE-aligned ranges, return a mapping size that may cover
multiple CONT_PTE blocks, capped below PMD_SIZE. These sizes are vmalloc
mapping spans, not HugeTLB hstate sizes.

Signed-off-by: Barry Song (Xiaomi) <[email protected]>
Signed-off-by: Wen Jiang <[email protected]>
Tested-by: Xueyuan Chen <[email protected]>
Tested-by: Leo Yan <[email protected]>
---
 arch/arm64/include/asm/vmalloc.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h
index 4ec1acd3c1b34..4053b1ec1902e 100644
--- a/arch/arm64/include/asm/vmalloc.h
+++ b/arch/arm64/include/asm/vmalloc.h
@@ -23,10 +23,14 @@ static inline unsigned long 
arch_vmap_pte_range_map_size(unsigned long addr,
                                                unsigned long end, u64 pfn,
                                                unsigned int max_page_shift)
 {
+       unsigned long size;
+
        /*
         * If the block is at least CONT_PTE_SIZE in size, and is naturally
         * aligned in both virtual and physical space, then we can pte-map the
         * block using the PTE_CONT bit for more efficient use of the TLB.
+        * The returned mapping size may cover multiple CONT_PTE_SIZE blocks,
+        * capped below PMD_SIZE.
         */
        if (max_page_shift < CONT_PTE_SHIFT)
                return PAGE_SIZE;
@@ -40,7 +44,9 @@ static inline unsigned long 
arch_vmap_pte_range_map_size(unsigned long addr,
        if (!IS_ALIGNED(PFN_PHYS(pfn), CONT_PTE_SIZE))
                return PAGE_SIZE;
 
-       return CONT_PTE_SIZE;
+       size = min3(end - addr, 1UL << max_page_shift, PMD_SIZE >> 1);
+       size = round_down(size, CONT_PTE_SIZE);
+       return size;
 }
 
 #define arch_vmap_pte_range_unmap_size arch_vmap_pte_range_unmap_size
-- 
2.34.1


Reply via email to