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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1994 - 2001 by Ralf Baechle
  7.  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8.  */
  9. #ifndef _ASM_PGALLOC_H
  10. #define _ASM_PGALLOC_H
  11. #include <linux/config.h>
  12. #include <linux/mm.h>
  13. #include <asm/fixmap.h>
  14. /* TLB flushing:
  15.  *
  16.  *  - flush_tlb_all() flushes all processes TLB entries
  17.  *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
  18.  *  - flush_tlb_page(mm, vmaddr) flushes a single page
  19.  *  - flush_tlb_range(mm, start, end) flushes a range of pages
  20.  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  21.  */
  22. extern void local_flush_tlb_all(void);
  23. extern void local_flush_tlb_mm(struct mm_struct *mm);
  24. extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
  25.        unsigned long end);
  26. extern void local_flush_tlb_page(struct vm_area_struct *vma,
  27.                                  unsigned long page);
  28. #ifdef CONFIG_SMP
  29. extern void flush_tlb_all(void);
  30. extern void flush_tlb_mm(struct mm_struct *);
  31. extern void flush_tlb_range(struct mm_struct *, unsigned long, unsigned long);
  32. extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
  33. #else /* CONFIG_SMP */
  34. #define flush_tlb_all() local_flush_tlb_all()
  35. #define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
  36. #define flush_tlb_range(mm,vmaddr,end) local_flush_tlb_range(mm, vmaddr, end)
  37. #define flush_tlb_page(vma,page) local_flush_tlb_page(vma, page)
  38. #endif /* CONFIG_SMP */
  39. static inline void flush_tlb_pgtables(struct mm_struct *mm,
  40.                                       unsigned long start, unsigned long end)
  41. {
  42. /* Nothing to do on MIPS.  */
  43. }
  44. /*
  45.  * Allocate and free page tables.
  46.  */
  47. #define pgd_quicklist (current_cpu_data.pgd_quick)
  48. #define pmd_quicklist ((unsigned long *)0)
  49. #define pte_quicklist (current_cpu_data.pte_quick)
  50. #define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
  51. #define pmd_populate(mm, pmd, pte) pmd_set(pmd, pte)
  52. /*
  53.  * Initialize new page directory with pointers to invalid ptes
  54.  */
  55. extern void pgd_init(unsigned long page);
  56. extern __inline__ pgd_t *get_pgd_slow(void)
  57. {
  58. pgd_t *ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGD_ORDER), *init;
  59. if (ret) {
  60. init = pgd_offset(&init_mm, 0);
  61. pgd_init((unsigned long)ret);
  62. memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
  63. (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
  64. }
  65. return ret;
  66. }
  67. extern __inline__ pgd_t *get_pgd_fast(void)
  68. {
  69. unsigned long *ret;
  70. if((ret = pgd_quicklist) != NULL) {
  71. pgd_quicklist = (unsigned long *)(*ret);
  72. ret[0] = ret[1];
  73. pgtable_cache_size--;
  74. } else
  75. ret = (unsigned long *)get_pgd_slow();
  76. return (pgd_t *)ret;
  77. }
  78. extern __inline__ void free_pgd_fast(pgd_t *pgd)
  79. {
  80. *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
  81. pgd_quicklist = (unsigned long *) pgd;
  82. pgtable_cache_size++;
  83. }
  84. extern __inline__ void free_pgd_slow(pgd_t *pgd)
  85. {
  86. free_pages((unsigned long)pgd, PGD_ORDER);
  87. }
  88. extern __inline__ pte_t *get_pte_fast(void)
  89. {
  90. unsigned long *ret;
  91. if((ret = (unsigned long *)pte_quicklist) != NULL) {
  92. pte_quicklist = (unsigned long *)(*ret);
  93. ret[0] = ret[1];
  94. pgtable_cache_size--;
  95. }
  96. return (pte_t *)ret;
  97. }
  98. extern __inline__ void free_pte_fast(pte_t *pte)
  99. {
  100. *(unsigned long *)pte = (unsigned long) pte_quicklist;
  101. pte_quicklist = (unsigned long *) pte;
  102. pgtable_cache_size++;
  103. }
  104. extern __inline__ void free_pte_slow(pte_t *pte)
  105. {
  106. free_page((unsigned long)pte);
  107. }
  108. /* We don't use pmd cache, so these are dummy routines */
  109. extern __inline__ pmd_t *get_pmd_fast(void)
  110. {
  111. return (pmd_t *)0;
  112. }
  113. extern __inline__ void free_pmd_fast(pmd_t *pmd)
  114. {
  115. }
  116. extern __inline__ void free_pmd_slow(pmd_t *pmd)
  117. {
  118. }
  119. extern void __bad_pte(pmd_t *pmd);
  120. static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  121. {
  122. pte_t *pte;
  123. pte = (pte_t *) __get_free_page(GFP_KERNEL);
  124. if (pte)
  125. clear_page(pte);
  126. return pte;
  127. }
  128. static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
  129. {
  130. unsigned long *ret;
  131. if ((ret = (unsigned long *)pte_quicklist) != NULL) {
  132. pte_quicklist = (unsigned long *)(*ret);
  133. ret[0] = ret[1];
  134. pgtable_cache_size--;
  135. }
  136. return (pte_t *)ret;
  137. }
  138. extern __inline__ void pte_free_fast(pte_t *pte)
  139. {
  140. *(unsigned long *)pte = (unsigned long) pte_quicklist;
  141. pte_quicklist = (unsigned long *) pte;
  142. pgtable_cache_size++;
  143. }
  144. extern __inline__ void pte_free_slow(pte_t *pte)
  145. {
  146. free_page((unsigned long)pte);
  147. }
  148. #define pte_free(pte)           pte_free_fast(pte)
  149. #define pgd_free(pgd)           free_pgd_fast(pgd)
  150. #define pgd_alloc(mm)           get_pgd_fast()
  151. /*
  152.  * allocating and freeing a pmd is trivial: the 1-entry pmd is
  153.  * inside the pgd, so has no extra memory associated with it.
  154.  */
  155. #define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); })
  156. #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
  157. #define pmd_free(x) do { } while (0)
  158. #define pgd_populate(mm, pmd, pte) BUG()
  159. extern int do_check_pgt_cache(int, int);
  160. #endif /* _ASM_PGALLOC_H */