v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / include / asm-arm / pgalloc.h
1 /*
2  *  linux/include/asm-arm/pgalloc.h
3  *
4  *  Copyright (C) 2000-2001 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 #ifndef _ASMARM_PGALLOC_H
11 #define _ASMARM_PGALLOC_H
12
13 #include <linux/config.h>
14
15 #include <asm/processor.h>
16
17 /*
18  * Get the cache handling stuff now.
19  */
20 #include <asm/proc/cache.h>
21
22 /*
23  * ARM processors do not cache TLB tables in RAM.
24  */
25 #define flush_tlb_pgtables(mm,start,end)        do { } while (0)
26
27 /*
28  * Processor specific parts...
29  */
30 #include <asm/proc/pgalloc.h>
31
32 /*
33  * Page table cache stuff
34  */
35 #ifndef CONFIG_NO_PGT_CACHE
36
37 #ifdef CONFIG_SMP
38 #error Pgtable caches have to be per-CPU, so that no locking is needed.
39 #endif  /* CONFIG_SMP */
40
41 extern struct pgtable_cache_struct {
42         unsigned long *pgd_cache;
43         unsigned long *pte_cache;
44         unsigned long pgtable_cache_sz;
45 } quicklists;
46
47 #define pgd_quicklist           (quicklists.pgd_cache)
48 #define pmd_quicklist           ((unsigned long *)0)
49 #define pte_quicklist           (quicklists.pte_cache)
50 #define pgtable_cache_size      (quicklists.pgtable_cache_sz)
51
52 /* used for quicklists */
53 #define __pgd_next(pgd) (((unsigned long *)pgd)[1])
54 #define __pte_next(pte) (((unsigned long *)pte)[0])
55
56 static inline pgd_t *get_pgd_fast(void)
57 {
58         unsigned long *ret;
59
60         if ((ret = pgd_quicklist) != NULL) {
61                 pgd_quicklist = (unsigned long *)__pgd_next(ret);
62                 ret[1] = ret[2];
63                 clean_dcache_entry(ret + 1);
64                 pgtable_cache_size--;
65         }
66         return (pgd_t *)ret;
67 }
68
69 static inline void free_pgd_fast(pgd_t *pgd)
70 {
71         __pgd_next(pgd) = (unsigned long) pgd_quicklist;
72         pgd_quicklist = (unsigned long *) pgd;
73         pgtable_cache_size++;
74 }
75
76 static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
77 {
78         unsigned long *ret;
79
80         if((ret = pte_quicklist) != NULL) {
81                 pte_quicklist = (unsigned long *)__pte_next(ret);
82                 ret[0] = 0;
83                 clean_dcache_entry(ret);
84                 pgtable_cache_size--;
85         }
86         return (pte_t *)ret;
87 }
88
89 static inline void free_pte_fast(pte_t *pte)
90 {
91         __pte_next(pte) = (unsigned long) pte_quicklist;
92         pte_quicklist = (unsigned long *) pte;
93         pgtable_cache_size++;
94 }
95
96 #else   /* CONFIG_NO_PGT_CACHE */
97
98 #define pgd_quicklist                   ((unsigned long *)0)
99 #define pmd_quicklist                   ((unsigned long *)0)
100 #define pte_quicklist                   ((unsigned long *)0)
101
102 #define get_pgd_fast()                  ((pgd_t *)0)
103 #define pte_alloc_one_fast(mm,addr)     ((pte_t *)0)
104
105 #define free_pgd_fast(pgd)              free_pgd_slow(pgd)
106 #define free_pte_fast(pte)              pte_free_slow(pte)
107
108 #endif  /* CONFIG_NO_PGT_CACHE */
109
110 #define pte_free(pte)                   free_pte_fast(pte)
111
112
113 /*
114  * Since we have only two-level page tables, these are trivial
115  */
116 #define pmd_alloc_one_fast(mm,addr)     ({ BUG(); ((pmd_t *)1); })
117 #define pmd_alloc_one(mm,addr)          ({ BUG(); ((pmd_t *)2); })
118 #define pmd_free_slow(pmd)              do { } while (0)
119 #define pmd_free_fast(pmd)              do { } while (0)
120 #define pmd_free(pmd)                   do { } while (0)
121 #define pgd_populate(mm,pmd,pte)        BUG()
122
123 extern pgd_t *get_pgd_slow(struct mm_struct *mm);
124 extern void free_pgd_slow(pgd_t *pgd);
125
126 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
127 {
128         pgd_t *pgd;
129
130         pgd = get_pgd_fast();
131         if (!pgd)
132                 pgd = get_pgd_slow(mm);
133
134         return pgd;
135 }
136
137 #define pgd_free(pgd)                   free_pgd_fast(pgd)
138
139 extern int do_check_pgt_cache(int, int);
140
141 #endif