diff options
Diffstat (limited to 'include/asm-avr32/pgalloc.h')
-rw-r--r-- | include/asm-avr32/pgalloc.h | 68 |
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 | ||
19 | static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | 18 | static 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 | |||
24 | static 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 | ||
31 | static 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 | */ |
29 | static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm) | 43 | static 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 | ||
34 | static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | 48 | static 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 | ||
39 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 53 | static 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 | ||
49 | static inline struct page *pte_alloc_one(struct mm_struct *mm, | 59 | static 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 | ||
61 | static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | 75 | static 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 | ||
66 | static inline void pte_free(struct mm_struct *mm, pgtable_t pte) | 80 | static 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) | 92 | static 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 */ |