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

asm-generic: pgalloc: provide generic pud_alloc_one() and pud_free_one()

Several architectures define pud_alloc_one() as a wrapper for
__get_free_page() and pud_free() as a wrapper for free_page().

Provide a generic implementation in asm-generic/pgalloc.h and use it where
appropriate.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Cc: Abdul Haleem <abdhalee@linux.vnet.ibm.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Joerg Roedel <jroedel@suse.de>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com>
Cc: Stafford Horne <shorne@gmail.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Matthew Wilcox <willy@infradead.org>
Link: http://lkml.kernel.org/r/20200627143453.31835-6-rppt@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Mike Rapoport and committed by
Linus Torvalds
d9e8b929 1355c31e

+31 -40
-11
arch/arm64/include/asm/pgalloc.h
··· 37 37 38 38 #if CONFIG_PGTABLE_LEVELS > 3 39 39 40 - static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) 41 - { 42 - return (pud_t *)__get_free_page(GFP_PGTABLE_USER); 43 - } 44 - 45 - static inline void pud_free(struct mm_struct *mm, pud_t *pudp) 46 - { 47 - BUG_ON((unsigned long)pudp & (PAGE_SIZE-1)); 48 - free_page((unsigned long)pudp); 49 - } 50 - 51 40 static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot) 52 41 { 53 42 set_p4d(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot));
-9
arch/ia64/include/asm/pgalloc.h
··· 41 41 p4d_val(*p4d_entry) = __pa(pud); 42 42 } 43 43 44 - static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) 45 - { 46 - return (pud_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO); 47 - } 48 - 49 - static inline void pud_free(struct mm_struct *mm, pud_t *pud) 50 - { 51 - free_page((unsigned long)pud); 52 - } 53 44 #define __pud_free_tlb(tlb, pud, address) pud_free((tlb)->mm, pud) 54 45 #endif /* CONFIG_PGTABLE_LEVELS == 4 */ 55 46
+1 -5
arch/mips/include/asm/pgalloc.h
··· 14 14 #include <linux/sched.h> 15 15 16 16 #define __HAVE_ARCH_PMD_ALLOC_ONE 17 + #define __HAVE_ARCH_PUD_ALLOC_ONE 17 18 #include <asm-generic/pgalloc.h> 18 19 19 20 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, ··· 86 85 if (pud) 87 86 pud_init((unsigned long)pud, (unsigned long)invalid_pmd_table); 88 87 return pud; 89 - } 90 - 91 - static inline void pud_free(struct mm_struct *mm, pud_t *pud) 92 - { 93 - free_pages((unsigned long)pud, PUD_ORDER); 94 88 } 95 89 96 90 static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud)
-15
arch/x86/include/asm/pgalloc.h
··· 123 123 set_p4d_safe(p4d, __p4d(_PAGE_TABLE | __pa(pud))); 124 124 } 125 125 126 - static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) 127 - { 128 - gfp_t gfp = GFP_KERNEL_ACCOUNT; 129 - 130 - if (mm == &init_mm) 131 - gfp &= ~__GFP_ACCOUNT; 132 - return (pud_t *)get_zeroed_page(gfp); 133 - } 134 - 135 - static inline void pud_free(struct mm_struct *mm, pud_t *pud) 136 - { 137 - BUG_ON((unsigned long)pud & (PAGE_SIZE-1)); 138 - free_page((unsigned long)pud); 139 - } 140 - 141 126 extern void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud); 142 127 143 128 static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
+30
include/asm-generic/pgalloc.h
··· 145 145 146 146 #endif /* CONFIG_PGTABLE_LEVELS > 2 */ 147 147 148 + #if CONFIG_PGTABLE_LEVELS > 3 149 + 150 + #ifndef __HAVE_ARCH_PUD_FREE 151 + /** 152 + * pud_alloc_one - allocate a page for PUD-level page table 153 + * @mm: the mm_struct of the current context 154 + * 155 + * Allocates a page using %GFP_PGTABLE_USER for user context and 156 + * %GFP_PGTABLE_KERNEL for kernel context. 157 + * 158 + * Return: pointer to the allocated memory or %NULL on error 159 + */ 160 + static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) 161 + { 162 + gfp_t gfp = GFP_PGTABLE_USER; 163 + 164 + if (mm == &init_mm) 165 + gfp = GFP_PGTABLE_KERNEL; 166 + return (pud_t *)get_zeroed_page(gfp); 167 + } 168 + #endif 169 + 170 + static inline void pud_free(struct mm_struct *mm, pud_t *pud) 171 + { 172 + BUG_ON((unsigned long)pud & (PAGE_SIZE-1)); 173 + free_page((unsigned long)pud); 174 + } 175 + 176 + #endif /* CONFIG_PGTABLE_LEVELS > 3 */ 177 + 148 178 #endif /* CONFIG_MMU */ 149 179 150 180 #endif /* __ASM_GENERIC_PGALLOC_H */