aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-avr32/pgalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-avr32/pgalloc.h')
-rw-r--r--include/asm-avr32/pgalloc.h68
1 files changed, 43 insertions, 25 deletions
diff --git a/include/asm-avr32/pgalloc.h b/include/asm-avr32/pgalloc.h
index 51fc1f6e4b17..640821323943 100644
--- a/include/asm-avr32/pgalloc.h
+++ b/include/asm-avr32/pgalloc.h
@@ -8,65 +8,79 @@
8#ifndef __ASM_AVR32_PGALLOC_H 8#ifndef __ASM_AVR32_PGALLOC_H
9#define __ASM_AVR32_PGALLOC_H 9#define __ASM_AVR32_PGALLOC_H
10 10
11#include <asm/processor.h> 11#include <linux/quicklist.h>
12#include <linux/threads.h> 12#include <asm/page.h>
13#include <linux/slab.h> 13#include <asm/pgtable.h>
14#include <linux/mm.h>
15 14
16#define pmd_populate_kernel(mm, pmd, pte) \ 15#define QUICK_PGD 0 /* Preserve kernel mappings over free */
17 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) 16#define QUICK_PT 1 /* Zero on free */
18 17
19static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 18static inline void pmd_populate_kernel(struct mm_struct *mm,
19 pmd_t *pmd, pte_t *pte)
20{
21 set_pmd(pmd, __pmd((unsigned long)pte));
22}
23
24static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
20 pgtable_t pte) 25 pgtable_t pte)
21{ 26{
22 set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte))); 27 set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
23} 28}
24#define pmd_pgtable(pmd) pmd_page(pmd) 29#define pmd_pgtable(pmd) pmd_page(pmd)
25 30
31static inline void pgd_ctor(void *x)
32{
33 pgd_t *pgd = x;
34
35 memcpy(pgd + USER_PTRS_PER_PGD,
36 swapper_pg_dir + USER_PTRS_PER_PGD,
37 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
38}
39
26/* 40/*
27 * Allocate and free page tables 41 * Allocate and free page tables
28 */ 42 */
29static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm) 43static inline pgd_t *pgd_alloc(struct mm_struct *mm)
30{ 44{
31 return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL); 45 return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
32} 46}
33 47
34static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 48static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
35{ 49{
36 kfree(pgd); 50 quicklist_free(QUICK_PGD, NULL, pgd);
37} 51}
38 52
39static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 53static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
40 unsigned long address) 54 unsigned long address)
41{ 55{
42 pte_t *pte; 56 return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
43
44 pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
45
46 return pte;
47} 57}
48 58
49static inline struct page *pte_alloc_one(struct mm_struct *mm, 59static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
50 unsigned long address) 60 unsigned long address)
51{ 61{
52 struct page *pte; 62 struct page *page;
63 void *pg;
53 64
54 pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); 65 pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
55 if (!pte) 66 if (!pg)
56 return NULL; 67 return NULL;
57 pgtable_page_ctor(pte); 68
58 return pte; 69 page = virt_to_page(pg);
70 pgtable_page_ctor(page);
71
72 return page;
59} 73}
60 74
61static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 75static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
62{ 76{
63 free_page((unsigned long)pte); 77 quicklist_free(QUICK_PT, NULL, pte);
64} 78}
65 79
66static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 80static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
67{ 81{
68 pgtable_page_dtor(pte); 82 pgtable_page_dtor(pte);
69 __free_page(pte); 83 quicklist_free_page(QUICK_PT, NULL, pte);
70} 84}
71 85
72#define __pte_free_tlb(tlb,pte) \ 86#define __pte_free_tlb(tlb,pte) \
@@ -75,6 +89,10 @@ do { \
75 tlb_remove_page((tlb), pte); \ 89 tlb_remove_page((tlb), pte); \
76} while (0) 90} while (0)
77 91
78#define check_pgt_cache() do { } while(0) 92static inline void check_pgt_cache(void)
93{
94 quicklist_trim(QUICK_PGD, NULL, 25, 16);
95 quicklist_trim(QUICK_PT, NULL, 25, 16);
96}
79 97
80#endif /* __ASM_AVR32_PGALLOC_H */ 98#endif /* __ASM_AVR32_PGALLOC_H */