1#ifndef _PPC64_PGALLOC_H 2#define _PPC64_PGALLOC_H 3 4#include <linux/threads.h> 5#include <asm/processor.h> 6#include <asm/naca.h> 7#include <asm/paca.h> 8 9/* 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 13 * 2 of the License, or (at your option) any later version. 14 */ 15#define quicklists get_paca() 16 17#define pgd_quicklist (quicklists->pgd_cache) 18#define pmd_quicklist (quicklists->pmd_cache) 19#define pte_quicklist (quicklists->pte_cache) 20#define pgtable_cache_size (quicklists->pgtable_cache_sz) 21 22static inline pgd_t* 23pgd_alloc_one_fast (struct mm_struct *mm) 24{ 25 unsigned long *ret = pgd_quicklist; 26 27 if (ret != NULL) { 28 pgd_quicklist = (unsigned long *)(*ret); 29 ret[0] = 0; 30 --pgtable_cache_size; 31 } else 32 ret = NULL; 33 return (pgd_t *) ret; 34} 35 36static inline pgd_t* 37pgd_alloc (struct mm_struct *mm) 38{ 39 /* the VM system never calls pgd_alloc_one_fast(), so we do it here. */ 40 pgd_t *pgd = pgd_alloc_one_fast(mm); 41 42 if (pgd == NULL) { 43 pgd = (pgd_t *)__get_free_page(GFP_KERNEL); 44 if (pgd != NULL) 45 clear_page(pgd); 46 } 47 return pgd; 48} 49 50static inline void 51pgd_free (pgd_t *pgd) 52{ 53 *(unsigned long *)pgd = (unsigned long) pgd_quicklist; 54 pgd_quicklist = (unsigned long *) pgd; 55 ++pgtable_cache_size; 56} 57 58#define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD) 59 60static inline pmd_t* 61pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr) 62{ 63 unsigned long *ret = (unsigned long *)pmd_quicklist; 64 65 if (ret != NULL) { 66 pmd_quicklist = (unsigned long *)(*ret); 67 ret[0] = 0; 68 --pgtable_cache_size; 69 } 70 return (pmd_t *)ret; 71} 72 73static inline pmd_t* 74pmd_alloc_one (struct mm_struct *mm, unsigned long addr) 75{ 76 pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL); 77 78 if (pmd != NULL) 79 clear_page(pmd); 80 return pmd; 81} 82 83static inline void 84pmd_free (pmd_t *pmd) 85{ 86 *(unsigned long *)pmd = (unsigned long) pmd_quicklist; 87 pmd_quicklist = (unsigned long *) pmd; 88 ++pgtable_cache_size; 89} 90 91#define pmd_populate(MM, PMD, PTE) pmd_set(PMD, PTE) 92 93static inline pte_t* 94pte_alloc_one_fast (struct mm_struct *mm, unsigned long addr) 95{ 96 unsigned long *ret = (unsigned long *)pte_quicklist; 97 98 if (ret != NULL) { 99 pte_quicklist = (unsigned long *)(*ret); 100 ret[0] = 0; 101 --pgtable_cache_size; 102 } 103 return (pte_t *)ret; 104} 105 106 107static inline pte_t* 108pte_alloc_one (struct mm_struct *mm, unsigned long addr) 109{ 110 pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL); 111 112 if (pte != NULL) 113 clear_page(pte); 114 return pte; 115} 116 117static inline void 118pte_free (pte_t *pte) 119{ 120 *(unsigned long *)pte = (unsigned long) pte_quicklist; 121 pte_quicklist = (unsigned long *) pte; 122 ++pgtable_cache_size; 123} 124 125extern int do_check_pgt_cache(int, int); 126 127#endif /* _PPC64_PGALLOC_H */ 128