pgalloc.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _X86_64_PGALLOC_H
  2. #define _X86_64_PGALLOC_H
  3. #include <linux/config.h>
  4. #include <asm/processor.h>
  5. #include <asm/fixmap.h>
  6. #include <asm/pda.h>
  7. #include <linux/threads.h>
  8. #include <linux/mm.h>
  9. #include <asm/page.h>
  10. #define inc_pgcache_size() add_pda(pgtable_cache_sz,1UL)
  11. #define dec_pgcache_size() sub_pda(pgtable_cache_sz,1UL)
  12. #define pmd_populate(mm, pmd, pte) 
  13. set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
  14. #define pgd_populate(mm, pgd, pmd) 
  15. set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pmd)))
  16. extern __inline__ pmd_t *get_pmd_slow(void)
  17. {
  18. return (pmd_t *)get_zeroed_page(GFP_KERNEL);
  19. }
  20. extern __inline__ pmd_t *get_pmd_fast(void)
  21. {
  22. unsigned long *ret;
  23. if ((ret = read_pda(pmd_quick)) != NULL) {
  24. write_pda(pmd_quick, (unsigned long *)(*ret));
  25. ret[0] = 0;
  26. dec_pgcache_size();
  27. } else
  28. ret = (unsigned long *)get_pmd_slow();
  29. return (pmd_t *)ret;
  30. }
  31. extern __inline__ void pmd_free(pmd_t *pmd)
  32. {
  33. *(unsigned long *)pmd = (unsigned long) read_pda(pmd_quick);
  34. write_pda(pmd_quick,(unsigned long *) pmd);
  35. inc_pgcache_size();
  36. }
  37. extern __inline__ void pmd_free_slow(pmd_t *pmd)
  38. {
  39. if ((unsigned long)pmd & (PAGE_SIZE-1)) 
  40. out_of_line_bug(); 
  41. free_page((unsigned long)pmd);
  42. }
  43. static inline pmd_t *pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
  44. {
  45. unsigned long *ret = (unsigned long *)read_pda(pmd_quick);
  46. if (ret != NULL) {
  47. write_pda(pmd_quick, (unsigned long *)(*ret));
  48. ret[0] = 0;
  49. dec_pgcache_size();
  50. }
  51. return (pmd_t *)ret;
  52. }
  53. static inline pmd_t *pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
  54. {
  55. return (pmd_t *)get_zeroed_page(GFP_KERNEL); 
  56. }
  57. static inline pgd_t *pgd_alloc_one_fast (void)
  58. {
  59. unsigned long *ret = read_pda(pgd_quick);
  60. if (ret) {
  61. write_pda(pgd_quick,(unsigned long *)(*ret));
  62. ret[0] = 0;
  63. dec_pgcache_size();
  64. }
  65. return (pgd_t *) ret;
  66. }
  67. static inline pgd_t *pgd_alloc (struct mm_struct *mm)
  68. {
  69. /* the VM system never calls pgd_alloc_one_fast(), so we do it here. */
  70. pgd_t *pgd = pgd_alloc_one_fast();
  71. if (pgd == NULL)
  72. pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); 
  73. return pgd;
  74. }
  75. static inline void pgd_free (pgd_t *pgd)
  76. {
  77. *(unsigned long *)pgd = (unsigned long) read_pda(pgd_quick);
  78. write_pda(pgd_quick,(unsigned long *) pgd);
  79. inc_pgcache_size();
  80. }
  81. static inline void pgd_free_slow (pgd_t *pgd)
  82. {
  83. if ((unsigned long)pgd & (PAGE_SIZE-1)) 
  84. out_of_line_bug(); 
  85. free_page((unsigned long)pgd);
  86. }
  87. static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  88. {
  89. return (pte_t *)get_zeroed_page(GFP_KERNEL); 
  90. }
  91. extern __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
  92. {
  93. unsigned long *ret;
  94. if ((ret = read_pda(pte_quick)) != NULL) {  
  95. write_pda(pte_quick, (unsigned long *)(*ret));
  96. ret[0] = ret[1];
  97. dec_pgcache_size();
  98. }
  99. return (pte_t *)ret;
  100. }
  101. /* Should really implement gc for free page table pages. This could be done with 
  102.    a reference count in struct page. */
  103. extern __inline__ void pte_free(pte_t *pte)
  104. {
  105. *(unsigned long *)pte = (unsigned long) read_pda(pte_quick);
  106. write_pda(pte_quick, (unsigned long *) pte); 
  107. inc_pgcache_size();
  108. }
  109. extern __inline__ void pte_free_slow(pte_t *pte)
  110. {
  111. if ((unsigned long)pte & (PAGE_SIZE-1))
  112. out_of_line_bug();
  113. free_page((unsigned long)pte); 
  114. }
  115. extern int do_check_pgt_cache(int, int);
  116. /*
  117.  * TLB flushing:
  118.  *
  119.  *  - flush_tlb() flushes the current mm struct TLBs
  120.  *  - flush_tlb_all() flushes all processes TLBs
  121.  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
  122.  *  - flush_tlb_page(vma, vmaddr) flushes one page
  123.  *  - flush_tlb_range(mm, start, end) flushes a range of pages
  124.  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  125.  */
  126. #ifndef CONFIG_SMP
  127. #define flush_tlb() __flush_tlb()
  128. #define flush_tlb_all() __flush_tlb_all()
  129. #define local_flush_tlb() __flush_tlb()
  130. static inline void flush_tlb_mm(struct mm_struct *mm)
  131. {
  132. if (mm == current->active_mm)
  133. __flush_tlb();
  134. }
  135. static inline void flush_tlb_page(struct vm_area_struct *vma,
  136. unsigned long addr)
  137. {
  138. if (vma->vm_mm == current->active_mm)
  139. __flush_tlb_one(addr);
  140. }
  141. static inline void flush_tlb_range(struct mm_struct *mm,
  142. unsigned long start, unsigned long end)
  143. {
  144. if (mm == current->active_mm)
  145. __flush_tlb();
  146. }
  147. #else
  148. #include <asm/smp.h>
  149. #define local_flush_tlb() 
  150. __flush_tlb()
  151. extern void flush_tlb_all(void);
  152. extern void flush_tlb_current_task(void);
  153. extern void flush_tlb_mm(struct mm_struct *);
  154. extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
  155. #define flush_tlb() flush_tlb_current_task()
  156. static inline void flush_tlb_range(struct mm_struct * mm, unsigned long start, unsigned long end)
  157. {
  158. flush_tlb_mm(mm);
  159. }
  160. #define TLBSTATE_OK 1
  161. #define TLBSTATE_LAZY 2
  162. struct tlb_state
  163. {
  164. struct mm_struct *active_mm;
  165. int state;
  166. };
  167. extern struct tlb_state cpu_tlbstate[NR_CPUS];
  168. #endif
  169. extern inline void flush_tlb_pgtables(struct mm_struct *mm,
  170.       unsigned long start, unsigned long end)
  171. {
  172. flush_tlb_mm(mm);
  173. }
  174. #endif /* _X86_64_PGALLOC_H */