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