Commit | Line | Data |
---|---|---|
2bc64a20 AK |
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 | ||
15 | #ifndef _LINUX_HUGETLB_CGROUP_H | |
16 | #define _LINUX_HUGETLB_CGROUP_H | |
17 | ||
309381fe | 18 | #include <linux/mmdebug.h> |
2bc64a20 AK |
19 | |
20 | struct hugetlb_cgroup; | |
e9fe92ae | 21 | struct resv_map; |
075a61d0 | 22 | struct file_region; |
e9fe92ae | 23 | |
cd39d4e9 | 24 | #ifdef CONFIG_CGROUP_HUGETLB |
9dd540e2 AK |
25 | /* |
26 | * Minimum page order trackable by hugetlb cgroup. | |
1adc4d41 | 27 | * At least 4 pages are necessary for all the tracking information. |
cd39d4e9 MS |
28 | * The second tail page (hpage[SUBPAGE_INDEX_CGROUP]) is the fault |
29 | * usage cgroup. The third tail page (hpage[SUBPAGE_INDEX_CGROUP_RSVD]) | |
30 | * is the reservation usage cgroup. | |
9dd540e2 | 31 | */ |
cd39d4e9 | 32 | #define HUGETLB_CGROUP_MIN_ORDER order_base_2(__MAX_CGROUP_SUBPAGE_INDEX + 1) |
2bc64a20 | 33 | |
e9fe92ae MA |
34 | enum hugetlb_memory_event { |
35 | HUGETLB_MAX, | |
36 | HUGETLB_NR_MEMORY_EVENTS, | |
37 | }; | |
38 | ||
39 | struct hugetlb_cgroup { | |
40 | struct cgroup_subsys_state css; | |
41 | ||
42 | /* | |
43 | * the counter to account for hugepages from hugetlb. | |
44 | */ | |
45 | struct page_counter hugepage[HUGE_MAX_HSTATE]; | |
46 | ||
47 | /* | |
48 | * the counter to account for hugepage reservations from hugetlb. | |
49 | */ | |
50 | struct page_counter rsvd_hugepage[HUGE_MAX_HSTATE]; | |
51 | ||
52 | atomic_long_t events[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS]; | |
53 | atomic_long_t events_local[HUGE_MAX_HSTATE][HUGETLB_NR_MEMORY_EVENTS]; | |
54 | ||
55 | /* Handle for "hugetlb.events" */ | |
56 | struct cgroup_file events_file[HUGE_MAX_HSTATE]; | |
57 | ||
58 | /* Handle for "hugetlb.events.local" */ | |
59 | struct cgroup_file events_local_file[HUGE_MAX_HSTATE]; | |
60 | }; | |
9dd540e2 | 61 | |
1adc4d41 MA |
62 | static inline struct hugetlb_cgroup * |
63 | __hugetlb_cgroup_from_page(struct page *page, bool rsvd) | |
9dd540e2 | 64 | { |
309381fe | 65 | VM_BUG_ON_PAGE(!PageHuge(page), page); |
9dd540e2 AK |
66 | |
67 | if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER) | |
68 | return NULL; | |
1adc4d41 | 69 | if (rsvd) |
cd39d4e9 | 70 | return (void *)page_private(page + SUBPAGE_INDEX_CGROUP_RSVD); |
1adc4d41 | 71 | else |
cd39d4e9 | 72 | return (void *)page_private(page + SUBPAGE_INDEX_CGROUP); |
1adc4d41 MA |
73 | } |
74 | ||
75 | static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page) | |
76 | { | |
77 | return __hugetlb_cgroup_from_page(page, false); | |
9dd540e2 AK |
78 | } |
79 | ||
1adc4d41 MA |
80 | static inline struct hugetlb_cgroup * |
81 | hugetlb_cgroup_from_page_rsvd(struct page *page) | |
82 | { | |
83 | return __hugetlb_cgroup_from_page(page, true); | |
84 | } | |
85 | ||
86 | static inline int __set_hugetlb_cgroup(struct page *page, | |
87 | struct hugetlb_cgroup *h_cg, bool rsvd) | |
9dd540e2 | 88 | { |
309381fe | 89 | VM_BUG_ON_PAGE(!PageHuge(page), page); |
9dd540e2 AK |
90 | |
91 | if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER) | |
92 | return -1; | |
1adc4d41 | 93 | if (rsvd) |
cd39d4e9 MS |
94 | set_page_private(page + SUBPAGE_INDEX_CGROUP_RSVD, |
95 | (unsigned long)h_cg); | |
1adc4d41 | 96 | else |
cd39d4e9 MS |
97 | set_page_private(page + SUBPAGE_INDEX_CGROUP, |
98 | (unsigned long)h_cg); | |
9dd540e2 AK |
99 | return 0; |
100 | } | |
101 | ||
1adc4d41 MA |
102 | static inline int set_hugetlb_cgroup(struct page *page, |
103 | struct hugetlb_cgroup *h_cg) | |
104 | { | |
105 | return __set_hugetlb_cgroup(page, h_cg, false); | |
106 | } | |
107 | ||
108 | static inline int set_hugetlb_cgroup_rsvd(struct page *page, | |
109 | struct hugetlb_cgroup *h_cg) | |
110 | { | |
111 | return __set_hugetlb_cgroup(page, h_cg, true); | |
112 | } | |
113 | ||
2bc64a20 AK |
114 | static inline bool hugetlb_cgroup_disabled(void) |
115 | { | |
fc5ed1e9 | 116 | return !cgroup_subsys_enabled(hugetlb_cgrp_subsys); |
2bc64a20 AK |
117 | } |
118 | ||
d85aecf2 ML |
119 | static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) |
120 | { | |
121 | css_put(&h_cg->css); | |
122 | } | |
123 | ||
09a26e83 MK |
124 | static inline void resv_map_dup_hugetlb_cgroup_uncharge_info( |
125 | struct resv_map *resv_map) | |
126 | { | |
127 | if (resv_map->css) | |
128 | css_get(resv_map->css); | |
129 | } | |
130 | ||
6d76dcf4 AK |
131 | extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, |
132 | struct hugetlb_cgroup **ptr); | |
1adc4d41 MA |
133 | extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages, |
134 | struct hugetlb_cgroup **ptr); | |
6d76dcf4 AK |
135 | extern void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages, |
136 | struct hugetlb_cgroup *h_cg, | |
137 | struct page *page); | |
1adc4d41 MA |
138 | extern void hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages, |
139 | struct hugetlb_cgroup *h_cg, | |
140 | struct page *page); | |
6d76dcf4 AK |
141 | extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, |
142 | struct page *page); | |
1adc4d41 MA |
143 | extern void hugetlb_cgroup_uncharge_page_rsvd(int idx, unsigned long nr_pages, |
144 | struct page *page); | |
145 | ||
6d76dcf4 AK |
146 | extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, |
147 | struct hugetlb_cgroup *h_cg); | |
1adc4d41 MA |
148 | extern void hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages, |
149 | struct hugetlb_cgroup *h_cg); | |
e9fe92ae MA |
150 | extern void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, |
151 | unsigned long start, | |
152 | unsigned long end); | |
1adc4d41 | 153 | |
075a61d0 MA |
154 | extern void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, |
155 | struct file_region *rg, | |
d85aecf2 ML |
156 | unsigned long nr_pages, |
157 | bool region_del); | |
075a61d0 | 158 | |
7179e7bf | 159 | extern void hugetlb_cgroup_file_init(void) __init; |
8e6ac7fa AK |
160 | extern void hugetlb_cgroup_migrate(struct page *oldhpage, |
161 | struct page *newhpage); | |
6d76dcf4 | 162 | |
2bc64a20 | 163 | #else |
075a61d0 MA |
164 | static inline void hugetlb_cgroup_uncharge_file_region(struct resv_map *resv, |
165 | struct file_region *rg, | |
d85aecf2 ML |
166 | unsigned long nr_pages, |
167 | bool region_del) | |
075a61d0 MA |
168 | { |
169 | } | |
170 | ||
9dd540e2 AK |
171 | static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page) |
172 | { | |
173 | return NULL; | |
174 | } | |
175 | ||
1adc4d41 MA |
176 | static inline struct hugetlb_cgroup * |
177 | hugetlb_cgroup_from_page_resv(struct page *page) | |
178 | { | |
179 | return NULL; | |
180 | } | |
181 | ||
182 | static inline struct hugetlb_cgroup * | |
183 | hugetlb_cgroup_from_page_rsvd(struct page *page) | |
184 | { | |
185 | return NULL; | |
186 | } | |
187 | ||
188 | static inline int set_hugetlb_cgroup(struct page *page, | |
189 | struct hugetlb_cgroup *h_cg) | |
190 | { | |
191 | return 0; | |
192 | } | |
193 | ||
194 | static inline int set_hugetlb_cgroup_rsvd(struct page *page, | |
195 | struct hugetlb_cgroup *h_cg) | |
9dd540e2 AK |
196 | { |
197 | return 0; | |
198 | } | |
199 | ||
2bc64a20 AK |
200 | static inline bool hugetlb_cgroup_disabled(void) |
201 | { | |
202 | return true; | |
203 | } | |
204 | ||
d85aecf2 ML |
205 | static inline void hugetlb_cgroup_put_rsvd_cgroup(struct hugetlb_cgroup *h_cg) |
206 | { | |
207 | } | |
208 | ||
09a26e83 MK |
209 | static inline void resv_map_dup_hugetlb_cgroup_uncharge_info( |
210 | struct resv_map *resv_map) | |
211 | { | |
212 | } | |
213 | ||
1adc4d41 MA |
214 | static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages, |
215 | struct hugetlb_cgroup **ptr) | |
6d76dcf4 AK |
216 | { |
217 | return 0; | |
218 | } | |
219 | ||
1adc4d41 MA |
220 | static inline int hugetlb_cgroup_charge_cgroup_rsvd(int idx, |
221 | unsigned long nr_pages, | |
222 | struct hugetlb_cgroup **ptr) | |
223 | { | |
224 | return 0; | |
225 | } | |
226 | ||
227 | static inline void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages, | |
228 | struct hugetlb_cgroup *h_cg, | |
229 | struct page *page) | |
6d76dcf4 | 230 | { |
6d76dcf4 AK |
231 | } |
232 | ||
233 | static inline void | |
1adc4d41 MA |
234 | hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages, |
235 | struct hugetlb_cgroup *h_cg, | |
236 | struct page *page) | |
237 | { | |
238 | } | |
239 | ||
240 | static inline void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, | |
241 | struct page *page) | |
242 | { | |
243 | } | |
244 | ||
245 | static inline void hugetlb_cgroup_uncharge_page_rsvd(int idx, | |
246 | unsigned long nr_pages, | |
247 | struct page *page) | |
248 | { | |
249 | } | |
250 | static inline void hugetlb_cgroup_uncharge_cgroup(int idx, | |
251 | unsigned long nr_pages, | |
252 | struct hugetlb_cgroup *h_cg) | |
6d76dcf4 | 253 | { |
6d76dcf4 AK |
254 | } |
255 | ||
256 | static inline void | |
1adc4d41 MA |
257 | hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages, |
258 | struct hugetlb_cgroup *h_cg) | |
6d76dcf4 | 259 | { |
6d76dcf4 AK |
260 | } |
261 | ||
e9fe92ae MA |
262 | static inline void hugetlb_cgroup_uncharge_counter(struct resv_map *resv, |
263 | unsigned long start, | |
264 | unsigned long end) | |
265 | { | |
266 | } | |
267 | ||
7179e7bf | 268 | static inline void hugetlb_cgroup_file_init(void) |
abb8206c | 269 | { |
abb8206c AK |
270 | } |
271 | ||
8e6ac7fa AK |
272 | static inline void hugetlb_cgroup_migrate(struct page *oldhpage, |
273 | struct page *newhpage) | |
274 | { | |
8e6ac7fa AK |
275 | } |
276 | ||
2bc64a20 AK |
277 | #endif /* CONFIG_MEM_RES_CTLR_HUGETLB */ |
278 | #endif |