Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

asm-generic: pgalloc: provide generic p4d_{alloc_one,free}

Four architectures currently implement 5-level pgtables: arm64, riscv, x86
and s390. The first three have essentially the same implementation for
p4d_alloc_one() and p4d_free(), so we've got an opportunity to reduce
duplication like at the lower levels.

Provide a generic version of p4d_alloc_one() and p4d_free(), and make use
of it on those architectures.

Their implementation is the same as at PUD level, except that p4d_free()
performs a runtime check by calling mm_p4d_folded(). 5-level pgtables
depend on a runtime-detected hardware feature on all supported
architectures, so we might as well include this check in the generic
implementation. No runtime check is required in p4d_alloc_one() as the
top-level p4d_alloc() already does the required check.

Link: https://lkml.kernel.org/r/26d69c74a29183ecc335b9b407040d8e4cd70c6a.1736317725.git.zhengqi.arch@bytedance.com
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de> [asm-generic]
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Andreas Larsson <andreas@gaisler.com>
Cc: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Mike Rapoport (Microsoft) <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yu Zhao <yuzhao@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Kevin Brodsky and committed by
Andrew Morton
98a7e47f 5a32443f

+45 -58
-17
arch/arm64/include/asm/pgalloc.h
··· 85 85 __pgd_populate(pgdp, __pa(p4dp), pgdval); 86 86 } 87 87 88 - static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr) 89 - { 90 - gfp_t gfp = GFP_PGTABLE_USER; 91 - 92 - if (mm == &init_mm) 93 - gfp = GFP_PGTABLE_KERNEL; 94 - return (p4d_t *)get_zeroed_page(gfp); 95 - } 96 - 97 - static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) 98 - { 99 - if (!pgtable_l5_enabled()) 100 - return; 101 - BUG_ON((unsigned long)p4d & (PAGE_SIZE-1)); 102 - free_page((unsigned long)p4d); 103 - } 104 - 105 88 #define __p4d_free_tlb(tlb, p4d, addr) p4d_free((tlb)->mm, p4d) 106 89 #else 107 90 static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t p4dp, pgdval_t prot)
-23
arch/riscv/include/asm/pgalloc.h
··· 105 105 } 106 106 } 107 107 108 - #define p4d_alloc_one p4d_alloc_one 109 - static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr) 110 - { 111 - gfp_t gfp = GFP_PGTABLE_USER; 112 - 113 - if (mm == &init_mm) 114 - gfp = GFP_PGTABLE_KERNEL; 115 - return (p4d_t *)get_zeroed_page(gfp); 116 - } 117 - 118 - static inline void __p4d_free(struct mm_struct *mm, p4d_t *p4d) 119 - { 120 - BUG_ON((unsigned long)p4d & (PAGE_SIZE-1)); 121 - free_page((unsigned long)p4d); 122 - } 123 - 124 - #define p4d_free p4d_free 125 - static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) 126 - { 127 - if (pgtable_l5_enabled) 128 - __p4d_free(mm, p4d); 129 - } 130 - 131 108 static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, 132 109 unsigned long addr) 133 110 {
-18
arch/x86/include/asm/pgalloc.h
··· 147 147 set_pgd_safe(pgd, __pgd(_PAGE_TABLE | __pa(p4d))); 148 148 } 149 149 150 - static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr) 151 - { 152 - gfp_t gfp = GFP_KERNEL_ACCOUNT; 153 - 154 - if (mm == &init_mm) 155 - gfp &= ~__GFP_ACCOUNT; 156 - return (p4d_t *)get_zeroed_page(gfp); 157 - } 158 - 159 - static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) 160 - { 161 - if (!pgtable_l5_enabled()) 162 - return; 163 - 164 - BUG_ON((unsigned long)p4d & (PAGE_SIZE-1)); 165 - free_page((unsigned long)p4d); 166 - } 167 - 168 150 extern void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d); 169 151 170 152 static inline void __p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d,
+45
include/asm-generic/pgalloc.h
··· 215 215 216 216 #endif /* CONFIG_PGTABLE_LEVELS > 3 */ 217 217 218 + #if CONFIG_PGTABLE_LEVELS > 4 219 + 220 + static inline p4d_t *__p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long addr) 221 + { 222 + gfp_t gfp = GFP_PGTABLE_USER; 223 + struct ptdesc *ptdesc; 224 + 225 + if (mm == &init_mm) 226 + gfp = GFP_PGTABLE_KERNEL; 227 + gfp &= ~__GFP_HIGHMEM; 228 + 229 + ptdesc = pagetable_alloc_noprof(gfp, 0); 230 + if (!ptdesc) 231 + return NULL; 232 + 233 + return ptdesc_address(ptdesc); 234 + } 235 + #define __p4d_alloc_one(...) alloc_hooks(__p4d_alloc_one_noprof(__VA_ARGS__)) 236 + 237 + #ifndef __HAVE_ARCH_P4D_ALLOC_ONE 238 + static inline p4d_t *p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long addr) 239 + { 240 + return __p4d_alloc_one_noprof(mm, addr); 241 + } 242 + #define p4d_alloc_one(...) alloc_hooks(p4d_alloc_one_noprof(__VA_ARGS__)) 243 + #endif 244 + 245 + static inline void __p4d_free(struct mm_struct *mm, p4d_t *p4d) 246 + { 247 + struct ptdesc *ptdesc = virt_to_ptdesc(p4d); 248 + 249 + BUG_ON((unsigned long)p4d & (PAGE_SIZE-1)); 250 + pagetable_free(ptdesc); 251 + } 252 + 253 + #ifndef __HAVE_ARCH_P4D_FREE 254 + static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) 255 + { 256 + if (!mm_p4d_folded(mm)) 257 + __p4d_free(mm, p4d); 258 + } 259 + #endif 260 + 261 + #endif /* CONFIG_PGTABLE_LEVELS > 4 */ 262 + 218 263 #ifndef __HAVE_ARCH_PGD_FREE 219 264 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 220 265 {