hugetlb_cgroup.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Copyright IBM Corporation, 2012
  3. * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2.1 of the GNU Lesser General Public License
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it would be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. *
  13. */
  14. #ifndef _LINUX_HUGETLB_CGROUP_H
  15. #define _LINUX_HUGETLB_CGROUP_H
  16. #include <linux/mmdebug.h>
  17. struct hugetlb_cgroup;
  18. struct resv_map;
  19. struct file_region;
  20. /*
  21. * Minimum page order trackable by hugetlb cgroup.
  22. * At least 4 pages are necessary for all the tracking information.
  23. * The second tail page (hpage[2]) is the fault usage cgroup.
  24. * The third tail page (hpage[3]) is the reservation usage cgroup.
  25. */
  26. #define HUGETLB_CGROUP_MIN_ORDER 2
  27. #ifdef CONFIG_CGROUP_HUGETLB
  28. enum hugetlb_memory_event {
  29. HUGETLB_MAX,
  30. HUGETLB_NR_MEMORY_EVENTS,
  31. };
  32. struct hugetlb_cgroup {
  33. struct cgroup_subsys_state css;
  34. /*
  35. * the counter to account for hugepages from hugetlb.
  36. */
  37. struct page_counter hugepage[HUGE_MAX_HSTATE];
  38. /*
  39. * the counter to account for hugepage reservations from hugetlb.
  40. */
  41. struct page_counter rsvd_hugepage[HUGE_MAX_HSTATE];
  42. atomic_long_t events[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS];
  43. atomic_long_t events_local[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS];
  44. /* Handle for "hugetlb.events" */
  45. struct cgroup_file events_file[HUGE_MAX_HSTATE];
  46. /* Handle for "hugetlb.events.local" */
  47. struct cgroup_file events_local_file[HUGE_MAX_HSTATE];
  48. };
  49. static inline struct hugetlb_cgroup *
  50. __hugetlb_cgroup_from_page(struct page *page, bool rsvd)
  51. {
  52. VM_BUG_ON_PAGE(!PageHuge(page), page);
  53. if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)
  54. return NULL;
  55. if (rsvd)
  56. return (struct hugetlb_cgroup *)page[3].private;
  57. else
  58. return (struct hugetlb_cgroup *)page[2].private;
  59. }
  60. static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
  61. {
  62. return __hugetlb_cgroup_from_page(page, false);
  63. }
  64. static inline struct hugetlb_cgroup *
  65. hugetlb_cgroup_from_page_rsvd(struct page *page)
  66. {
  67. return __hugetlb_cgroup_from_page(page, true);
  68. }
  69. static inline int __set_hugetlb_cgroup(struct page *page,
  70. struct hugetlb_cgroup *h_cg, bool rsvd)
  71. {
  72. VM_BUG_ON_PAGE(!PageHuge(page), page);
  73. if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)
  74. return -1;
  75. if (rsvd)
  76. page[3].private = (unsigned long)h_cg;
  77. else
  78. page[2].private = (unsigned long)h_cg;
  79. return 0;
  80. }
  81. static inline int set_hugetlb_cgroup(struct page *page,
  82. struct hugetlb_cgroup *h_cg)
  83. {
  84. return __set_hugetlb_cgroup(page, h_cg, false);
  85. }
  86. static inline int set_hugetlb_cgroup_rsvd(struct page *page,
  87. struct hugetlb_cgroup *h_cg)
  88. {
  89. return __set_hugetlb_cgroup(page, h_cg, true);
  90. }
  91. static inline bool hugetlb_cgroup_disabled(void)
  92. {
  93. return !cgroup_subsys_enabled(hugetlb_cgrp_subsys);
  94. }
  95. static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg)
  96. {
  97. css_put(&h_cg->css);
  98. }
  99. static inline void resv_map_dup_hugetlb_cgroup_uncharge_info(
  100. struct resv_map *resv_map)
  101. {
  102. if (resv_map->css)
  103. css_get(resv_map->css);
  104. }
  105. extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
  106. struct hugetlb_cgroup **ptr);
  107. extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages,
  108. struct hugetlb_cgroup **ptr);
  109. extern void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
  110. struct hugetlb_cgroup *h_cg,
  111. struct page *page);
  112. extern void hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
  113. struct hugetlb_cgroup *h_cg,
  114. struct page *page);
  115. extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
  116. struct page *page);
  117. extern void hugetlb_cgroup_uncharge_page_rsvd(int idx, unsigned long nr_pages,
  118. struct page *page);
  119. extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
  120. struct hugetlb_cgroup *h_cg);
  121. extern void hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
  122. struct hugetlb_cgroup *h_cg);
  123. extern void hugetlb_cgroup_uncharge_counter(struct resv_map *resv,
  124. unsigned long start,
  125. unsigned long end);
  126. extern void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv,
  127. struct file_region *rg,
  128. unsigned long nr_pages,
  129. bool region_del);
  130. extern void hugetlb_cgroup_file_init(void) __init;
  131. extern void hugetlb_cgroup_migrate(struct page *oldhpage,
  132. struct page *newhpage);
  133. #else
  134. static inline void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv,
  135. struct file_region *rg,
  136. unsigned long nr_pages,
  137. bool region_del)
  138. {
  139. }
  140. static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
  141. {
  142. return NULL;
  143. }
  144. static inline struct hugetlb_cgroup *
  145. hugetlb_cgroup_from_page_resv(struct page *page)
  146. {
  147. return NULL;
  148. }
  149. static inline struct hugetlb_cgroup *
  150. hugetlb_cgroup_from_page_rsvd(struct page *page)
  151. {
  152. return NULL;
  153. }
  154. static inline int set_hugetlb_cgroup(struct page *page,
  155. struct hugetlb_cgroup *h_cg)
  156. {
  157. return 0;
  158. }
  159. static inline int set_hugetlb_cgroup_rsvd(struct page *page,
  160. struct hugetlb_cgroup *h_cg)
  161. {
  162. return 0;
  163. }
  164. static inline bool hugetlb_cgroup_disabled(void)
  165. {
  166. return true;
  167. }
  168. static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg)
  169. {
  170. }
  171. static inline void resv_map_dup_hugetlb_cgroup_uncharge_info(
  172. struct resv_map *resv_map)
  173. {
  174. }
  175. static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
  176. struct hugetlb_cgroup **ptr)
  177. {
  178. return 0;
  179. }
  180. static inline int hugetlb_cgroup_charge_cgroup_rsvd(int idx,
  181. unsigned long nr_pages,
  182. struct hugetlb_cgroup **ptr)
  183. {
  184. return 0;
  185. }
  186. static inline void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
  187. struct hugetlb_cgroup *h_cg,
  188. struct page *page)
  189. {
  190. }
  191. static inline void
  192. hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
  193. struct hugetlb_cgroup *h_cg,
  194. struct page *page)
  195. {
  196. }
  197. static inline void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
  198. struct page *page)
  199. {
  200. }
  201. static inline void hugetlb_cgroup_uncharge_page_rsvd(int idx,
  202. unsigned long nr_pages,
  203. struct page *page)
  204. {
  205. }
  206. static inline void hugetlb_cgroup_uncharge_cgroup(int idx,
  207. unsigned long nr_pages,
  208. struct hugetlb_cgroup *h_cg)
  209. {
  210. }
  211. static inline void
  212. hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
  213. struct hugetlb_cgroup *h_cg)
  214. {
  215. }
  216. static inline void hugetlb_cgroup_uncharge_counter(struct resv_map *resv,
  217. unsigned long start,
  218. unsigned long end)
  219. {
  220. }
  221. static inline void hugetlb_cgroup_file_init(void)
  222. {
  223. }
  224. static inline void hugetlb_cgroup_migrate(struct page *oldhpage,
  225. struct page *newhpage)
  226. {
  227. }
  228. #endif /* CONFIG_MEM_RES_CTLR_HUGETLB */
  229. #endif