1 #ifndef _I386_PGALLOC_3LEVEL_H
2 #define _I386_PGALLOC_3LEVEL_H
3
4 /*
5 * Intel Physical Address Extension (PAE) Mode - three-level page
6 * tables on PPro+ CPUs. Page-table allocation routines.
7 *
8 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
9 */
10
11 extern __inline__ pmd_t *get_pmd_slow(void)
12 {
13 pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL);
14
15 if (ret)
16 memset(ret, 0, PAGE_SIZE);
17 return ret;
18 }
19
20 extern __inline__ pmd_t *get_pmd_fast(void)
21 {
22 unsigned long *ret;
23
24 if ((ret = pmd_quicklist) != NULL) {
25 pmd_quicklist = (unsigned long *)(*ret);
26 ret[0] = 0;
27 pgtable_cache_size--;
28 } else
29 ret = (unsigned long *)get_pmd_slow();
30 return (pmd_t *)ret;
31 }
32
33 extern __inline__ void free_pmd_fast(pmd_t *pmd)
34 {
35 *(unsigned long *)pmd = (unsigned long) pmd_quicklist;
36 pmd_quicklist = (unsigned long *) pmd;
37 pgtable_cache_size++;
38 }
39
40 extern __inline__ void free_pmd_slow(pmd_t *pmd)
41 {
42 free_page((unsigned long)pmd);
43 }
44
45 extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
46 {
47 if (!pgd)
48 BUG();
49 address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
50 if (pgd_none(*pgd)) {
51 pmd_t *page = get_pmd_fast();
52
53 if (!page)
54 page = get_pmd_slow();
55 if (page) {
56 if (pgd_none(*pgd)) {
57 set_pgd(pgd, __pgd(1 + __pa(page)));
58 __flush_tlb();
59 return page + address;
60 } else
61 free_pmd_fast(page);
62 } else
63 return NULL;
64 }
65 return (pmd_t *)pgd_page(*pgd) + address;
66 }
67
68 #endif /* _I386_PGALLOC_3LEVEL_H */
69
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.