home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-powerpc / pgalloc.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.9 KB  |  161 lines

  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.  
  14. extern 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.  
  36. static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  37. {
  38.     return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
  39. }
  40.  
  41. static 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.  
  50. static 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.  
  56. static inline void pud_free(pud_t *pud)
  57. {
  58.     kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
  59. }
  60.  
  61. static 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.  
  75. static 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.  
  86. static 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.  
  92. static inline void pmd_free(pmd_t *pmd)
  93. {
  94.     kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
  95. }
  96.  
  97. static 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.  
  104. static 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.         
  110. static inline void pte_free_kernel(pte_t *pte)
  111. {
  112.     kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte);
  113. }
  114.  
  115. static inline void pte_free(struct page *ptepage)
  116. {
  117.     pte_free_kernel(page_address(ptepage));
  118. }
  119.  
  120. #define PGF_CACHENUM_MASK    0xf
  121.  
  122. typedef struct pgtable_free {
  123.     unsigned long val;
  124. } pgtable_free_t;
  125.  
  126. static 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.  
  134. static 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.  
  142. extern 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 */
  161.