pgalloc.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

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 at alii
  7.  * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  8.  */
  9. #ifndef _ASM_PGALLOC_H
  10. #define _ASM_PGALLOC_H
  11. #include <linux/config.h>
  12. /* TLB flushing:
  13.  *
  14.  *  - flush_tlb_all() flushes all processes TLB entries
  15.  *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
  16.  *  - flush_tlb_page(mm, vmaddr) flushes a single page
  17.  *  - flush_tlb_range(mm, start, end) flushes a range of pages
  18.  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  19.  */
  20. extern void (*_flush_tlb_all)(void);
  21. extern void (*_flush_tlb_mm)(struct mm_struct *mm);
  22. extern void (*_flush_tlb_range)(struct mm_struct *mm, unsigned long start,
  23.        unsigned long end);
  24. extern void (*_flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
  25. #ifndef CONFIG_SMP
  26. #define flush_tlb_all() _flush_tlb_all()
  27. #define flush_tlb_mm(mm) _flush_tlb_mm(mm)
  28. #define flush_tlb_range(mm,vmaddr,end) _flush_tlb_range(mm, vmaddr, end)
  29. #define flush_tlb_page(vma,page) _flush_tlb_page(vma, page)
  30. #else /* CONFIG_SMP */
  31. extern void flush_tlb_all(void);
  32. extern void flush_tlb_mm(struct mm_struct *);
  33. extern void flush_tlb_range(struct mm_struct *, unsigned long, unsigned long);
  34. extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
  35. #endif /* CONFIG_SMP */
  36. extern inline void flush_tlb_pgtables(struct mm_struct *mm,
  37.                                       unsigned long start, unsigned long end)
  38. {
  39. /* Nothing to do on MIPS.  */
  40. }
  41. /*
  42.  * Allocate and free page tables.
  43.  */
  44. #define pgd_quicklist (current_cpu_data.pgd_quick)
  45. #define pmd_quicklist (current_cpu_data.pmd_quick)
  46. #define pte_quicklist (current_cpu_data.pte_quick)
  47. #define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
  48. #define pmd_populate(mm, pmd, pte) pmd_set(pmd, pte)
  49. #define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd)
  50. extern pgd_t *get_pgd_slow(void);
  51. extern inline pgd_t *get_pgd_fast(void)
  52. {
  53. unsigned long *ret;
  54. if((ret = pgd_quicklist) != NULL) {
  55. pgd_quicklist = (unsigned long *)(*ret);
  56. ret[0] = ret[1];
  57. pgtable_cache_size--;
  58. return (pgd_t *)ret;
  59. }
  60. ret = (unsigned long *) get_pgd_slow();
  61. return (pgd_t *)ret;
  62. }
  63. extern inline void free_pgd_fast(pgd_t *pgd)
  64. {
  65. *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
  66. pgd_quicklist = (unsigned long *) pgd;
  67. pgtable_cache_size++;
  68. }
  69. extern inline void free_pgd_slow(pgd_t *pgd)
  70. {
  71. free_pages((unsigned long)pgd, 1);
  72. }
  73. static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  74. {
  75. pte_t *pte;
  76. pte = (pte_t *) __get_free_page(GFP_KERNEL);
  77. if (pte)
  78. clear_page(pte);
  79. return pte;
  80. }
  81. static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
  82. {
  83. unsigned long *ret;
  84. if ((ret = (unsigned long *)pte_quicklist) != NULL) {
  85. pte_quicklist = (unsigned long *)(*ret);
  86. ret[0] = ret[1];
  87. pgtable_cache_size--;
  88. }
  89. return (pte_t *)ret;
  90. }
  91. extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
  92. extern inline pte_t *get_pte_fast(void)
  93. {
  94. unsigned long *ret;
  95. if((ret = (unsigned long *)pte_quicklist) != NULL) {
  96. pte_quicklist = (unsigned long *)(*ret);
  97. ret[0] = ret[1];
  98. pgtable_cache_size--;
  99. }
  100. return (pte_t *)ret;
  101. }
  102. extern inline void free_pte_fast(pte_t *pte)
  103. {
  104. *(unsigned long *)pte = (unsigned long) pte_quicklist;
  105. pte_quicklist = (unsigned long *) pte;
  106. pgtable_cache_size++;
  107. }
  108. extern inline void free_pte_slow(pte_t *pte)
  109. {
  110. free_pages((unsigned long)pte, 0);
  111. }
  112. static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
  113. {
  114. pmd_t *pmd;
  115. pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 1);
  116. if (pmd)
  117. pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
  118. return pmd;
  119. }
  120. static inline pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address)
  121. {
  122. unsigned long *ret;
  123. if ((ret = (unsigned long *)pmd_quicklist) != NULL) {
  124. pmd_quicklist = (unsigned long *)(*ret);
  125. ret[0] = ret[1];
  126. pgtable_cache_size--;
  127. }
  128. return (pmd_t *)ret;
  129. }
  130. extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_preadjusted);
  131. extern inline pmd_t *get_pmd_fast(void)
  132. {
  133. unsigned long *ret;
  134. if ((ret = (unsigned long *)pmd_quicklist) != NULL) {
  135. pmd_quicklist = (unsigned long *)(*ret);
  136. ret[0] = ret[1];
  137. pgtable_cache_size--;
  138. return (pmd_t *)ret;
  139. }
  140. return (pmd_t *)ret;
  141. }
  142. extern inline void free_pmd_fast(pmd_t *pmd)
  143. {
  144. *(unsigned long *)pmd = (unsigned long) pmd_quicklist;
  145. pmd_quicklist = (unsigned long *) pmd;
  146. pgtable_cache_size++;
  147. }
  148. extern inline void free_pmd_slow(pmd_t *pmd)
  149. {
  150. free_pages((unsigned long)pmd, 1);
  151. }
  152. #define pte_free(pte)           free_pte_fast(pte)
  153. #define pmd_free(pte)           free_pmd_fast(pte)
  154. #define pgd_free(pgd)           free_pgd_fast(pgd)
  155. #define pgd_alloc(mm)           get_pgd_fast()
  156. extern pte_t kptbl[(PAGE_SIZE<<KPTBL_PAGE_ORDER)/sizeof(pte_t)];
  157. extern pmd_t kpmdtbl[PTRS_PER_PMD];
  158. extern int do_check_pgt_cache(int, int);
  159. #endif /* _ASM_PGALLOC_H */