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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.pgalloc.h 1.9 05/17/01 18:14:25 cort
  3.  */
  4. #ifdef __KERNEL__
  5. #ifndef _PPC_PGALLOC_H
  6. #define _PPC_PGALLOC_H
  7. #include <linux/config.h>
  8. #include <linux/threads.h>
  9. #include <asm/processor.h>
  10. /*
  11.  * This is handled very differently on the PPC since out page tables
  12.  * are all 0's and I want to be able to use these zero'd pages elsewhere
  13.  * as well - it gives us quite a speedup.
  14.  *
  15.  * Note that the SMP/UP versions are the same but we don't need a
  16.  * per cpu list of zero pages because we do the zero-ing with the cache
  17.  * off and the access routines are lock-free but the pgt cache stuff
  18.  * is per-cpu since it isn't done with any lock-free access routines
  19.  * (although I think we need arch-specific routines so I can do lock-free).
  20.  *
  21.  * I need to generalize this so we can use it for other arch's as well.
  22.  * -- Cort
  23.  */
  24. #ifdef CONFIG_SMP
  25. #define quicklists cpu_data[smp_processor_id()]
  26. #else
  27. extern struct pgtable_cache_struct {
  28. unsigned long *pgd_cache;
  29. unsigned long *pte_cache;
  30. unsigned long pgtable_cache_sz;
  31. } quicklists;
  32. #endif
  33. #define pgd_quicklist  (quicklists.pgd_cache)
  34. #define pmd_quicklist  ((unsigned long *)0)
  35. #define pte_quicklist  (quicklists.pte_cache)
  36. #define pgtable_cache_size  (quicklists.pgtable_cache_sz)
  37. extern unsigned long *zero_cache;    /* head linked list of pre-zero'd pages */
  38. extern atomic_t zero_sz;      /* # currently pre-zero'd pages */
  39. extern atomic_t zeropage_hits;      /* # zero'd pages request that we've done */
  40. extern atomic_t zeropage_calls;      /* # zero'd pages request that've been made */
  41. extern atomic_t zerototal;      /* # pages zero'd over time */
  42. #define zero_quicklist      (zero_cache)
  43. #define zero_cache_sz     (zero_sz)
  44. #define zero_cache_calls  (zeropage_calls)
  45. #define zero_cache_hits   (zeropage_hits)
  46. #define zero_cache_total  (zerototal)
  47. /* return a pre-zero'd page from the list, return NULL if none available -- Cort */
  48. extern unsigned long get_zero_page_fast(void);
  49. extern void __bad_pte(pmd_t *pmd);
  50. extern __inline__ pgd_t *get_pgd_slow(void)
  51. {
  52. pgd_t *ret;
  53. if ((ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL)
  54. clear_page(ret);
  55. return ret;
  56. }
  57. extern __inline__ pgd_t *get_pgd_fast(void)
  58. {
  59.         unsigned long *ret;
  60.         if ((ret = pgd_quicklist) != NULL) {
  61.                 pgd_quicklist = (unsigned long *)(*ret);
  62.                 ret[0] = 0;
  63.                 pgtable_cache_size--;
  64.         } else
  65.                 ret = (unsigned long *)get_pgd_slow();
  66.         return (pgd_t *)ret;
  67. }
  68. extern __inline__ void free_pgd_fast(pgd_t *pgd)
  69. {
  70.         *(unsigned long **)pgd = pgd_quicklist;
  71.         pgd_quicklist = (unsigned long *) pgd;
  72.         pgtable_cache_size++;
  73. }
  74. extern __inline__ void free_pgd_slow(pgd_t *pgd)
  75. {
  76. free_page((unsigned long)pgd);
  77. }
  78. #define pgd_free(pgd) free_pgd_fast(pgd)
  79. #define pgd_alloc(mm) get_pgd_fast()
  80. /*
  81.  * We don't have any real pmd's, and this code never triggers because
  82.  * the pgd will always be present..
  83.  */
  84. #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
  85. #define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
  86. #define pmd_free(x)                     do { } while (0)
  87. #define pgd_populate(mm, pmd, pte)      BUG()
  88. static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  89. {
  90. pte_t *pte;
  91. extern int mem_init_done;
  92. extern void *early_get_page(void);
  93. if (mem_init_done)
  94. pte = (pte_t *) __get_free_page(GFP_KERNEL);
  95. else
  96. pte = (pte_t *) early_get_page();
  97. if (pte != NULL)
  98. clear_page(pte);
  99. return pte;
  100. }
  101. static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
  102. {
  103.         unsigned long *ret;
  104.         if ((ret = pte_quicklist) != NULL) {
  105.                 pte_quicklist = (unsigned long *)(*ret);
  106.                 ret[0] = 0;
  107.                 pgtable_cache_size--;
  108. }
  109.         return (pte_t *)ret;
  110. }
  111. extern __inline__ void pte_free_fast(pte_t *pte)
  112. {
  113.         *(unsigned long **)pte = pte_quicklist;
  114.         pte_quicklist = (unsigned long *) pte;
  115.         pgtable_cache_size++;
  116. }
  117. extern __inline__ void pte_free_slow(pte_t *pte)
  118. {
  119. free_page((unsigned long)pte);
  120. }
  121. #define pte_free(pte)    pte_free_slow(pte)
  122. #define pmd_populate(mm, pmd, pte) (pmd_val(*(pmd)) = (unsigned long) (pte))
  123. extern int do_check_pgt_cache(int, int);
  124. #endif /* _PPC_PGALLOC_H */
  125. #endif /* __KERNEL__ */