percpu-internal.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #ifndef _MM_PERCPU_INTERNAL_H
  2. #define _MM_PERCPU_INTERNAL_H
  3. #include <linux/types.h>
  4. #include <linux/percpu.h>
  5. struct pcpu_chunk {
  6. #ifdef CONFIG_PERCPU_STATS
  7. int nr_alloc; /* # of allocations */
  8. size_t max_alloc_size; /* largest allocation size */
  9. #endif
  10. struct list_head list; /* linked to pcpu_slot lists */
  11. int free_size; /* free bytes in the chunk */
  12. int contig_hint; /* max contiguous size hint */
  13. void *base_addr; /* base address of this chunk */
  14. int map_used; /* # of map entries used before the sentry */
  15. int map_alloc; /* # of map entries allocated */
  16. int *map; /* allocation map */
  17. struct list_head map_extend_list;/* on pcpu_map_extend_chunks */
  18. void *data; /* chunk data */
  19. int first_free; /* no free below this */
  20. bool immutable; /* no [de]population allowed */
  21. int start_offset; /* the overlap with the previous
  22. region to have a page aligned
  23. base_addr */
  24. int nr_populated; /* # of populated pages */
  25. unsigned long populated[]; /* populated bitmap */
  26. };
  27. extern spinlock_t pcpu_lock;
  28. extern struct list_head *pcpu_slot;
  29. extern int pcpu_nr_slots;
  30. extern int pcpu_nr_empty_pop_pages;
  31. extern struct pcpu_chunk *pcpu_first_chunk;
  32. extern struct pcpu_chunk *pcpu_reserved_chunk;
  33. #ifdef CONFIG_PERCPU_STATS
  34. #include <linux/spinlock.h>
  35. struct percpu_stats {
  36. u64 nr_alloc; /* lifetime # of allocations */
  37. u64 nr_dealloc; /* lifetime # of deallocations */
  38. u64 nr_cur_alloc; /* current # of allocations */
  39. u64 nr_max_alloc; /* max # of live allocations */
  40. u32 nr_chunks; /* current # of live chunks */
  41. u32 nr_max_chunks; /* max # of live chunks */
  42. size_t min_alloc_size; /* min allocaiton size */
  43. size_t max_alloc_size; /* max allocation size */
  44. };
  45. extern struct percpu_stats pcpu_stats;
  46. extern struct pcpu_alloc_info pcpu_stats_ai;
  47. /*
  48. * For debug purposes. We don't care about the flexible array.
  49. */
  50. static inline void pcpu_stats_save_ai(const struct pcpu_alloc_info *ai)
  51. {
  52. memcpy(&pcpu_stats_ai, ai, sizeof(struct pcpu_alloc_info));
  53. /* initialize min_alloc_size to unit_size */
  54. pcpu_stats.min_alloc_size = pcpu_stats_ai.unit_size;
  55. }
  56. /*
  57. * pcpu_stats_area_alloc - increment area allocation stats
  58. * @chunk: the location of the area being allocated
  59. * @size: size of area to allocate in bytes
  60. *
  61. * CONTEXT:
  62. * pcpu_lock.
  63. */
  64. static inline void pcpu_stats_area_alloc(struct pcpu_chunk *chunk, size_t size)
  65. {
  66. lockdep_assert_held(&pcpu_lock);
  67. pcpu_stats.nr_alloc++;
  68. pcpu_stats.nr_cur_alloc++;
  69. pcpu_stats.nr_max_alloc =
  70. max(pcpu_stats.nr_max_alloc, pcpu_stats.nr_cur_alloc);
  71. pcpu_stats.min_alloc_size =
  72. min(pcpu_stats.min_alloc_size, size);
  73. pcpu_stats.max_alloc_size =
  74. max(pcpu_stats.max_alloc_size, size);
  75. chunk->nr_alloc++;
  76. chunk->max_alloc_size = max(chunk->max_alloc_size, size);
  77. }
  78. /*
  79. * pcpu_stats_area_dealloc - decrement allocation stats
  80. * @chunk: the location of the area being deallocated
  81. *
  82. * CONTEXT:
  83. * pcpu_lock.
  84. */
  85. static inline void pcpu_stats_area_dealloc(struct pcpu_chunk *chunk)
  86. {
  87. lockdep_assert_held(&pcpu_lock);
  88. pcpu_stats.nr_dealloc++;
  89. pcpu_stats.nr_cur_alloc--;
  90. chunk->nr_alloc--;
  91. }
  92. /*
  93. * pcpu_stats_chunk_alloc - increment chunk stats
  94. */
  95. static inline void pcpu_stats_chunk_alloc(void)
  96. {
  97. unsigned long flags;
  98. spin_lock_irqsave(&pcpu_lock, flags);
  99. pcpu_stats.nr_chunks++;
  100. pcpu_stats.nr_max_chunks =
  101. max(pcpu_stats.nr_max_chunks, pcpu_stats.nr_chunks);
  102. spin_unlock_irqrestore(&pcpu_lock, flags);
  103. }
  104. /*
  105. * pcpu_stats_chunk_dealloc - decrement chunk stats
  106. */
  107. static inline void pcpu_stats_chunk_dealloc(void)
  108. {
  109. unsigned long flags;
  110. spin_lock_irqsave(&pcpu_lock, flags);
  111. pcpu_stats.nr_chunks--;
  112. spin_unlock_irqrestore(&pcpu_lock, flags);
  113. }
  114. #else
  115. static inline void pcpu_stats_save_ai(const struct pcpu_alloc_info *ai)
  116. {
  117. }
  118. static inline void pcpu_stats_area_alloc(struct pcpu_chunk *chunk, size_t size)
  119. {
  120. }
  121. static inline void pcpu_stats_area_dealloc(struct pcpu_chunk *chunk)
  122. {
  123. }
  124. static inline void pcpu_stats_chunk_alloc(void)
  125. {
  126. }
  127. static inline void pcpu_stats_chunk_dealloc(void)
  128. {
  129. }
  130. #endif /* !CONFIG_PERCPU_STATS */
  131. #endif