diff options
author | Hugh Dickins <hugh@veritas.com> | 2007-05-09 00:38:48 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-05-09 02:35:00 -0400 |
commit | 517e22638c282bb07c52a11f928961ed4822196b (patch) | |
tree | 7eab8eb1242ee18f75c325077f26bdcb86133512 /include/asm-powerpc | |
parent | f1fa74f4afe96b0e4ac2beaa61fa4f4667acdcbb (diff) |
[POWERPC] Don't use SLAB/SLUB for PTE pages
The SLUB allocator relies on struct page fields first_page and slab,
overwritten by ptl when SPLIT_PTLOCK: so the SLUB allocator cannot then
be used for the lowest level of pagetable pages. This was obstructing
SLUB on PowerPC, which uses kmem_caches for its pagetables. So convert
its pte level to use normal gfp pages (whereas pmd, pud and 64k-page pgd
want partpages, so continue to use kmem_caches for pmd, pud and pgd).
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r-- | include/asm-powerpc/pgalloc-64.h | 31 |
1 files changed, 13 insertions, 18 deletions
diff --git a/include/asm-powerpc/pgalloc-64.h b/include/asm-powerpc/pgalloc-64.h index 30b50cf56e2c..d9a3a8ca58a1 100644 --- a/include/asm-powerpc/pgalloc-64.h +++ b/include/asm-powerpc/pgalloc-64.h | |||
@@ -14,18 +14,11 @@ | |||
14 | 14 | ||
15 | extern struct kmem_cache *pgtable_cache[]; | 15 | extern struct kmem_cache *pgtable_cache[]; |
16 | 16 | ||
17 | #ifdef CONFIG_PPC_64K_PAGES | 17 | #define PGD_CACHE_NUM 0 |
18 | #define PTE_CACHE_NUM 0 | 18 | #define PUD_CACHE_NUM 1 |
19 | #define PMD_CACHE_NUM 1 | 19 | #define PMD_CACHE_NUM 1 |
20 | #define PGD_CACHE_NUM 2 | 20 | #define HUGEPTE_CACHE_NUM 2 |
21 | #define HUGEPTE_CACHE_NUM 3 | 21 | #define PTE_NONCACHE_NUM 3 /* from GFP rather than kmem_cache */ |
22 | #else | ||
23 | #define PTE_CACHE_NUM 0 | ||
24 | #define PMD_CACHE_NUM 1 | ||
25 | #define PUD_CACHE_NUM 1 | ||
26 | #define PGD_CACHE_NUM 0 | ||
27 | #define HUGEPTE_CACHE_NUM 2 | ||
28 | #endif | ||
29 | 22 | ||
30 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 23 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
31 | { | 24 | { |
@@ -91,8 +84,7 @@ static inline void pmd_free(pmd_t *pmd) | |||
91 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 84 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
92 | unsigned long address) | 85 | unsigned long address) |
93 | { | 86 | { |
94 | return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM], | 87 | return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); |
95 | GFP_KERNEL|__GFP_REPEAT); | ||
96 | } | 88 | } |
97 | 89 | ||
98 | static inline struct page *pte_alloc_one(struct mm_struct *mm, | 90 | static inline struct page *pte_alloc_one(struct mm_struct *mm, |
@@ -103,12 +95,12 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, | |||
103 | 95 | ||
104 | static inline void pte_free_kernel(pte_t *pte) | 96 | static inline void pte_free_kernel(pte_t *pte) |
105 | { | 97 | { |
106 | kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte); | 98 | free_page((unsigned long)pte); |
107 | } | 99 | } |
108 | 100 | ||
109 | static inline void pte_free(struct page *ptepage) | 101 | static inline void pte_free(struct page *ptepage) |
110 | { | 102 | { |
111 | pte_free_kernel(page_address(ptepage)); | 103 | __free_page(ptepage); |
112 | } | 104 | } |
113 | 105 | ||
114 | #define PGF_CACHENUM_MASK 0x3 | 106 | #define PGF_CACHENUM_MASK 0x3 |
@@ -130,14 +122,17 @@ static inline void pgtable_free(pgtable_free_t pgf) | |||
130 | void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK); | 122 | void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK); |
131 | int cachenum = pgf.val & PGF_CACHENUM_MASK; | 123 | int cachenum = pgf.val & PGF_CACHENUM_MASK; |
132 | 124 | ||
133 | kmem_cache_free(pgtable_cache[cachenum], p); | 125 | if (cachenum == PTE_NONCACHE_NUM) |
126 | free_page((unsigned long)p); | ||
127 | else | ||
128 | kmem_cache_free(pgtable_cache[cachenum], p); | ||
134 | } | 129 | } |
135 | 130 | ||
136 | extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); | 131 | extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); |
137 | 132 | ||
138 | #define __pte_free_tlb(tlb, ptepage) \ | 133 | #define __pte_free_tlb(tlb, ptepage) \ |
139 | pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \ | 134 | pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \ |
140 | PTE_CACHE_NUM, PTE_TABLE_SIZE-1)) | 135 | PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)) |
141 | #define __pmd_free_tlb(tlb, pmd) \ | 136 | #define __pmd_free_tlb(tlb, pmd) \ |
142 | pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ | 137 | pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ |
143 | PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) | 138 | PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) |