at v2.6.14 3.1 kB view raw
1#ifndef _PPC64_PGALLOC_H 2#define _PPC64_PGALLOC_H 3 4#include <linux/mm.h> 5#include <linux/slab.h> 6#include <linux/cpumask.h> 7#include <linux/percpu.h> 8 9extern kmem_cache_t *pgtable_cache[]; 10 11#define PTE_CACHE_NUM 0 12#define PMD_CACHE_NUM 1 13#define PUD_CACHE_NUM 1 14#define PGD_CACHE_NUM 0 15 16/* 17 * This program is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU General Public License 19 * as published by the Free Software Foundation; either version 20 * 2 of the License, or (at your option) any later version. 21 */ 22 23static inline pgd_t *pgd_alloc(struct mm_struct *mm) 24{ 25 return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL); 26} 27 28static inline void pgd_free(pgd_t *pgd) 29{ 30 kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd); 31} 32 33#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD) 34 35static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) 36{ 37 return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM], 38 GFP_KERNEL|__GFP_REPEAT); 39} 40 41static inline void pud_free(pud_t *pud) 42{ 43 kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud); 44} 45 46#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) 47 48static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) 49{ 50 return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM], 51 GFP_KERNEL|__GFP_REPEAT); 52} 53 54static inline void pmd_free(pmd_t *pmd) 55{ 56 kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd); 57} 58 59#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte) 60#define pmd_populate(mm, pmd, pte_page) \ 61 pmd_populate_kernel(mm, pmd, page_address(pte_page)) 62 63static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 64{ 65 return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM], 66 GFP_KERNEL|__GFP_REPEAT); 67} 68 69static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) 70{ 71 return virt_to_page(pte_alloc_one_kernel(mm, address)); 72} 73 74static inline void pte_free_kernel(pte_t *pte) 75{ 76 kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte); 77} 78 79static inline void pte_free(struct page *ptepage) 80{ 81 pte_free_kernel(page_address(ptepage)); 82} 83 84#define PGF_CACHENUM_MASK 0xf 85 86typedef struct pgtable_free { 87 unsigned long val; 88} pgtable_free_t; 89 90static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum, 91 unsigned long mask) 92{ 93 BUG_ON(cachenum > PGF_CACHENUM_MASK); 94 95 return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum}; 96} 97 98static inline void pgtable_free(pgtable_free_t pgf) 99{ 100 void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK); 101 int cachenum = pgf.val & PGF_CACHENUM_MASK; 102 103 kmem_cache_free(pgtable_cache[cachenum], p); 104} 105 106void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); 107 108#define __pte_free_tlb(tlb, ptepage) \ 109 pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \ 110 PTE_CACHE_NUM, PTE_TABLE_SIZE-1)) 111#define __pmd_free_tlb(tlb, pmd) \ 112 pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ 113 PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) 114#define __pud_free_tlb(tlb, pmd) \ 115 pgtable_free_tlb(tlb, pgtable_free_cache(pud, \ 116 PUD_CACHE_NUM, PUD_TABLE_SIZE-1)) 117 118#define check_pgt_cache() do { } while (0) 119 120#endif /* _PPC64_PGALLOC_H */