17 #include <linux/slab.h>
22 struct cgroup_subsys_state
css;
29 #define MEMFILE_PRIVATE(x, val) (((x) << 16) | (val))
30 #define MEMFILE_IDX(val) (((val) >> 16) & 0xffff)
31 #define MEMFILE_ATTR(val) ((val) & 0xffff)
37 struct hugetlb_cgroup *hugetlb_cgroup_from_css(
struct cgroup_subsys_state *
s)
43 struct hugetlb_cgroup *hugetlb_cgroup_from_cgroup(
struct cgroup *cgroup)
45 return hugetlb_cgroup_from_css(cgroup_subsys_state(cgroup,
52 return hugetlb_cgroup_from_css(task_subsys_state(task,
56 static inline bool hugetlb_cgroup_is_root(
struct hugetlb_cgroup *h_cg)
58 return (h_cg == root_h_cgroup);
61 static inline struct hugetlb_cgroup *parent_hugetlb_cgroup(
struct cgroup *cg)
65 return hugetlb_cgroup_from_cgroup(cg->parent);
68 static inline bool hugetlb_cgroup_have_usage(
struct cgroup *cg)
73 for (idx = 0; idx < hugetlb_max_hstate; idx++) {
80 static struct cgroup_subsys_state *hugetlb_cgroup_create(
struct cgroup *cgroup)
83 struct cgroup *parent_cgroup;
86 h_cgroup = kzalloc(
sizeof(*h_cgroup),
GFP_KERNEL);
90 parent_cgroup = cgroup->parent;
92 parent_h_cgroup = hugetlb_cgroup_from_cgroup(parent_cgroup);
97 root_h_cgroup = h_cgroup;
101 return &h_cgroup->
css;
104 static void hugetlb_cgroup_destroy(
struct cgroup *cgroup)
108 h_cgroup = hugetlb_cgroup_from_cgroup(cgroup);
120 static void hugetlb_cgroup_move_parent(
int idx,
struct cgroup *cgroup,
130 page_hcg = hugetlb_cgroup_from_page(page);
136 if (!page_hcg || page_hcg != h_cg)
139 csize =
PAGE_SIZE << compound_order(page);
141 parent = root_h_cgroup;
149 set_hugetlb_cgroup(page, parent);
158 static int hugetlb_cgroup_pre_destroy(
struct cgroup *cgroup)
162 int ret = 0, idx = 0;
166 !list_empty(&cgroup->children)) {
171 spin_lock(&hugetlb_lock);
173 hugetlb_cgroup_move_parent(idx, cgroup, page);
175 spin_unlock(&hugetlb_lock);
179 } while (hugetlb_cgroup_have_usage(cgroup));
190 unsigned long csize = nr_pages *
PAGE_SIZE;
192 if (hugetlb_cgroup_disabled())
202 h_cg = hugetlb_cgroup_from_task(
current);
203 if (!css_tryget(&h_cg->
css)) {
221 if (hugetlb_cgroup_disabled() || !h_cg)
224 set_hugetlb_cgroup(page, h_cg);
235 unsigned long csize = nr_pages *
PAGE_SIZE;
237 if (hugetlb_cgroup_disabled())
239 VM_BUG_ON(!spin_is_locked(&hugetlb_lock));
240 h_cg = hugetlb_cgroup_from_page(page);
243 set_hugetlb_cgroup(page,
NULL);
251 unsigned long csize = nr_pages *
PAGE_SIZE;
253 if (hugetlb_cgroup_disabled() || !h_cg)
263 static ssize_t hugetlb_cgroup_read(
struct cgroup *cgroup,
struct cftype *cft,
265 size_t nbytes, loff_t *ppos)
276 len =
scnprintf(str,
sizeof(str),
"%llu\n", (
unsigned long long)val);
280 static int hugetlb_cgroup_write(
struct cgroup *cgroup,
struct cftype *cft,
284 unsigned long long val;
292 if (hugetlb_cgroup_is_root(h_cg)) {
301 ret = res_counter_set_limit(&h_cg->
hugepage[idx], val);
310 static int hugetlb_cgroup_reset(
struct cgroup *cgroup,
unsigned int event)
320 res_counter_reset_max(&h_cg->
hugepage[idx]);
323 res_counter_reset_failcnt(&h_cg->
hugepage[idx]);
332 static char *mem_fmt(
char *buf,
int size,
unsigned long hsize)
334 if (hsize >= (1
UL << 30))
335 snprintf(buf, size,
"%luGB", hsize >> 30);
336 else if (hsize >= (1
UL << 20))
337 snprintf(buf, size,
"%luMB", hsize >> 20);
339 snprintf(buf, size,
"%luKB", hsize >> 10);
353 cft = &h->cgroup_files[0];
354 snprintf(cft->name, MAX_CFTYPE_NAME,
"%s.limit_in_bytes", buf);
356 cft->read = hugetlb_cgroup_read;
357 cft->write_string = hugetlb_cgroup_write;
360 cft = &h->cgroup_files[1];
361 snprintf(cft->name, MAX_CFTYPE_NAME,
"%s.usage_in_bytes", buf);
363 cft->read = hugetlb_cgroup_read;
366 cft = &h->cgroup_files[2];
367 snprintf(cft->name, MAX_CFTYPE_NAME,
"%s.max_usage_in_bytes", buf);
369 cft->trigger = hugetlb_cgroup_reset;
370 cft->read = hugetlb_cgroup_read;
373 cft = &h->cgroup_files[3];
374 snprintf(cft->name, MAX_CFTYPE_NAME,
"%s.failcnt", buf);
376 cft->trigger = hugetlb_cgroup_reset;
377 cft->read = hugetlb_cgroup_read;
380 cft = &h->cgroup_files[4];
381 memset(cft, 0,
sizeof(*cft));
395 struct hstate *h = page_hstate(oldhpage);
397 if (hugetlb_cgroup_disabled())
401 spin_lock(&hugetlb_lock);
402 h_cg = hugetlb_cgroup_from_page(oldhpage);
403 set_hugetlb_cgroup(oldhpage,
NULL);
406 set_hugetlb_cgroup(newhpage, h_cg);
407 list_move(&newhpage->
lru, &h->hugepage_activelist);
408 spin_unlock(&hugetlb_lock);
414 .create = hugetlb_cgroup_create,
415 .pre_destroy = hugetlb_cgroup_pre_destroy,
416 .destroy = hugetlb_cgroup_destroy,
417 .subsys_id = hugetlb_subsys_id,