make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / include / asm-mips / pgalloc.h
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1994 - 2001 by Ralf Baechle
7  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8  */
9 #ifndef _ASM_PGALLOC_H
10 #define _ASM_PGALLOC_H
11
12 #include <linux/config.h>
13 #include <linux/mm.h>
14 #include <asm/fixmap.h>
15
16 /* TLB flushing:
17  *
18  *  - flush_tlb_all() flushes all processes TLB entries
19  *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
20  *  - flush_tlb_page(mm, vmaddr) flushes a single page
21  *  - flush_tlb_range(mm, start, end) flushes a range of pages
22  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
23  */
24 extern void local_flush_tlb_all(void);
25 extern void local_flush_tlb_mm(struct mm_struct *mm);
26 extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
27                                unsigned long end);
28 extern void local_flush_tlb_page(struct vm_area_struct *vma,
29                                  unsigned long page);
30
31 #ifdef CONFIG_SMP
32
33 extern void flush_tlb_all(void);
34 extern void flush_tlb_mm(struct mm_struct *);
35 extern void flush_tlb_range(struct mm_struct *, unsigned long, unsigned long);
36 extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
37
38 #else /* CONFIG_SMP */
39
40 #define flush_tlb_all()                 local_flush_tlb_all()
41 #define flush_tlb_mm(mm)                local_flush_tlb_mm(mm)
42 #define flush_tlb_range(mm,vmaddr,end)  local_flush_tlb_range(mm, vmaddr, end)
43 #define flush_tlb_page(vma,page)        local_flush_tlb_page(vma, page)
44
45 #endif /* CONFIG_SMP */
46
47 static inline void flush_tlb_pgtables(struct mm_struct *mm,
48                                       unsigned long start, unsigned long end)
49 {
50         /* Nothing to do on MIPS.  */
51 }
52
53
54 /*
55  * Allocate and free page tables.
56  */
57
58 #define pgd_quicklist (current_cpu_data.pgd_quick)
59 #define pmd_quicklist ((unsigned long *)0)
60 #define pte_quicklist (current_cpu_data.pte_quick)
61 #define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
62
63 #define pmd_populate(mm, pmd, pte)      pmd_set(pmd, pte)
64
65 /*
66  * Initialize new page directory with pointers to invalid ptes
67  */
68 extern void pgd_init(unsigned long page);
69
70 extern __inline__ pgd_t *get_pgd_slow(void)
71 {
72         pgd_t *ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGD_ORDER), *init;
73
74         if (ret) {
75                 init = pgd_offset(&init_mm, 0);
76                 pgd_init((unsigned long)ret);
77                 memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
78                         (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
79         }
80         return ret;
81 }
82
83 extern __inline__ pgd_t *get_pgd_fast(void)
84 {
85         unsigned long *ret;
86
87         if((ret = pgd_quicklist) != NULL) {
88                 pgd_quicklist = (unsigned long *)(*ret);
89                 ret[0] = ret[1];
90                 pgtable_cache_size--;
91         } else
92                 ret = (unsigned long *)get_pgd_slow();
93         return (pgd_t *)ret;
94 }
95
96 extern __inline__ void free_pgd_fast(pgd_t *pgd)
97 {
98         *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
99         pgd_quicklist = (unsigned long *) pgd;
100         pgtable_cache_size++;
101 }
102
103 extern __inline__ void free_pgd_slow(pgd_t *pgd)
104 {
105         free_pages((unsigned long)pgd, PGD_ORDER);
106 }
107
108 extern __inline__ pte_t *get_pte_fast(void)
109 {
110         unsigned long *ret;
111
112         if((ret = (unsigned long *)pte_quicklist) != NULL) {
113                 pte_quicklist = (unsigned long *)(*ret);
114                 ret[0] = ret[1];
115                 pgtable_cache_size--;
116         }
117         return (pte_t *)ret;
118 }
119
120 extern __inline__ void free_pte_fast(pte_t *pte)
121 {
122         *(unsigned long *)pte = (unsigned long) pte_quicklist;
123         pte_quicklist = (unsigned long *) pte;
124         pgtable_cache_size++;
125 }
126
127 extern __inline__ void free_pte_slow(pte_t *pte)
128 {
129         free_page((unsigned long)pte);
130 }
131
132 /* We don't use pmd cache, so these are dummy routines */
133 extern __inline__ pmd_t *get_pmd_fast(void)
134 {
135         return (pmd_t *)0;
136 }
137
138 extern __inline__ void free_pmd_fast(pmd_t *pmd)
139 {
140 }
141
142 extern __inline__ void free_pmd_slow(pmd_t *pmd)
143 {
144 }
145
146 extern void __bad_pte(pmd_t *pmd);
147
148 static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
149 {
150         pte_t *pte;
151
152         pte = (pte_t *) __get_free_page(GFP_KERNEL);
153         if (pte)
154                 clear_page(pte);
155         return pte;
156 }
157
158 static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
159 {
160         unsigned long *ret;
161
162         if ((ret = (unsigned long *)pte_quicklist) != NULL) {
163                 pte_quicklist = (unsigned long *)(*ret);
164                 ret[0] = ret[1];
165                 pgtable_cache_size--;
166         }
167         return (pte_t *)ret;
168 }
169
170 extern __inline__ void pte_free_fast(pte_t *pte)
171 {
172         *(unsigned long *)pte = (unsigned long) pte_quicklist;
173         pte_quicklist = (unsigned long *) pte;
174         pgtable_cache_size++;
175 }
176
177 extern __inline__ void pte_free_slow(pte_t *pte)
178 {
179         free_page((unsigned long)pte);
180 }
181
182 #define pte_free(pte)           pte_free_fast(pte)
183 #define pgd_free(pgd)           free_pgd_fast(pgd)
184 #define pgd_alloc(mm)           get_pgd_fast()
185
186 /*
187  * allocating and freeing a pmd is trivial: the 1-entry pmd is
188  * inside the pgd, so has no extra memory associated with it.
189  */
190 #define pmd_alloc_one_fast(mm, addr)    ({ BUG(); ((pmd_t *)1); })
191 #define pmd_alloc_one(mm, addr)         ({ BUG(); ((pmd_t *)2); })
192 #define pmd_free(x)                     do { } while (0)
193 #define pgd_populate(mm, pmd, pte)      BUG()
194
195 extern int do_check_pgt_cache(int, int);
196
197 #endif /* _ASM_PGALLOC_H */