On Thu, 8 Aug 2019 16:13:36 -0700 Mina Almasry wrote: > > These counters will track hugetlb reservations rather than hugetlb > memory faulted in. This patch only adds the counter, following patches > add the charging and uncharging of the counter. > --- !?! > include/linux/hugetlb.h | 2 +- > mm/hugetlb_cgroup.c | 86 +++++++++++++++++++++++++++++++++++++---- > 2 files changed, 80 insertions(+), 8 deletions(-) > > diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h > index edfca42783192..6777b3013345d 100644 > --- a/include/linux/hugetlb.h > +++ b/include/linux/hugetlb.h > @@ -340,7 +340,7 @@ struct hstate { > unsigned int surplus_huge_pages_node[MAX_NUMNODES]; > #ifdef CONFIG_CGROUP_HUGETLB > /* cgroup control files */ > - struct cftype cgroup_files[5]; > + struct cftype cgroup_files[9]; Move that enum in this header file and replace numbers with characters to easy both reading and maintaining. > #endif > char name[HSTATE_NAME_LEN]; > }; > diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c > index 68c2f2f3c05b7..708103663988a 100644 > --- a/mm/hugetlb_cgroup.c > +++ b/mm/hugetlb_cgroup.c > @@ -25,6 +25,10 @@ struct hugetlb_cgroup { > * the counter to account for hugepages from hugetlb. > */ > struct page_counter hugepage[HUGE_MAX_HSTATE]; > + /* > + * the counter to account for hugepage reservations from hugetlb. > + */ > + struct page_counter reserved_hugepage[HUGE_MAX_HSTATE]; > }; > > #define MEMFILE_PRIVATE(x, val) (((x) << 16) | (val)) > @@ -33,6 +37,15 @@ struct hugetlb_cgroup { > > static struct hugetlb_cgroup *root_h_cgroup __read_mostly; > > +static inline > +struct page_counter *get_counter(struct hugetlb_cgroup *h_cg, int idx, > + bool reserved) s/get_/hugetlb_cgroup_get_/ to make it not too generic. > +{ > + if (reserved) > + return &h_cg->reserved_hugepage[idx]; > + return &h_cg->hugepage[idx]; > +} > + > static inline > struct hugetlb_cgroup *hugetlb_cgroup_from_css(struct cgroup_subsys_state *s) > { > @@ -256,28 +269,42 @@ void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages, > > enum { > RES_USAGE, > + RES_RESERVATION_USAGE, > RES_LIMIT, > + RES_RESERVATION_LIMIT, > RES_MAX_USAGE, > + RES_RESERVATION_MAX_USAGE, > RES_FAILCNT, > + RES_RESERVATION_FAILCNT, > }; > > static u64 hugetlb_cgroup_read_u64(struct cgroup_subsys_state *css, > struct cftype *cft) > { > struct page_counter *counter; > + struct page_counter *reserved_counter; > struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(css); > > counter = &h_cg->hugepage[MEMFILE_IDX(cft->private)]; > + reserved_counter = &h_cg->reserved_hugepage[MEMFILE_IDX(cft->private)]; > > switch (MEMFILE_ATTR(cft->private)) { > case RES_USAGE: > return (u64)page_counter_read(counter) * PAGE_SIZE; > + case RES_RESERVATION_USAGE: > + return (u64)page_counter_read(reserved_counter) * PAGE_SIZE; > case RES_LIMIT: > return (u64)counter->max * PAGE_SIZE; > + case RES_RESERVATION_LIMIT: > + return (u64)reserved_counter->max * PAGE_SIZE; > case RES_MAX_USAGE: > return (u64)counter->watermark * PAGE_SIZE; > + case RES_RESERVATION_MAX_USAGE: > + return (u64)reserved_counter->watermark * PAGE_SIZE; > case RES_FAILCNT: > return counter->failcnt; > + case RES_RESERVATION_FAILCNT: > + return reserved_counter->failcnt; > default: > BUG(); > } > @@ -291,6 +318,7 @@ static ssize_t hugetlb_cgroup_write(struct kernfs_open_file *of, > int ret, idx; > unsigned long nr_pages; > struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(of_css(of)); > + bool reserved = false; > > if (hugetlb_cgroup_is_root(h_cg)) /* Can't set limit on root */ > return -EINVAL; > @@ -303,10 +331,16 @@ static ssize_t hugetlb_cgroup_write(struct kernfs_open_file *of, > idx = MEMFILE_IDX(of_cft(of)->private); > nr_pages = round_down(nr_pages, 1 << huge_page_order(&hstates[idx])); > > + if (MEMFILE_ATTR(of_cft(of)->private) == RES_RESERVATION_LIMIT) { > + reserved = true; > + } > + > switch (MEMFILE_ATTR(of_cft(of)->private)) { > + case RES_RESERVATION_LIMIT: reserved = true; /* fall thru */ > case RES_LIMIT: > mutex_lock(&hugetlb_limit_mutex); > - ret = page_counter_set_max(&h_cg->hugepage[idx], nr_pages); > + ret = page_counter_set_max(get_counter(h_cg, idx, reserved), > + nr_pages); > mutex_unlock(&hugetlb_limit_mutex); > break; > default: > @@ -320,18 +354,26 @@ static ssize_t hugetlb_cgroup_reset(struct kernfs_open_file *of, > char *buf, size_t nbytes, loff_t off) > { > int ret = 0; > - struct page_counter *counter; > + struct page_counter *counter, *reserved_counter; > struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_css(of_css(of)); > > counter = &h_cg->hugepage[MEMFILE_IDX(of_cft(of)->private)]; > + reserved_counter = &h_cg->reserved_hugepage[ > + MEMFILE_IDX(of_cft(of)->private)]; > > switch (MEMFILE_ATTR(of_cft(of)->private)) { > case RES_MAX_USAGE: > page_counter_reset_watermark(counter); > break; > + case RES_RESERVATION_MAX_USAGE: > + page_counter_reset_watermark(reserved_counter); > + break; > case RES_FAILCNT: > counter->failcnt = 0; > break; > + case RES_RESERVATION_FAILCNT: > + reserved_counter->failcnt = 0; > + break; > default: > ret = -EINVAL; > break; > @@ -357,7 +399,7 @@ static void __init __hugetlb_cgroup_file_init(int idx) > struct hstate *h = &hstates[idx]; > > /* format the size */ > - mem_fmt(buf, 32, huge_page_size(h)); > + mem_fmt(buf, sizeof(buf), huge_page_size(h)); > > /* Add the limit file */ > cft = &h->cgroup_files[0]; > @@ -366,28 +408,58 @@ static void __init __hugetlb_cgroup_file_init(int idx) > cft->read_u64 = hugetlb_cgroup_read_u64; > cft->write = hugetlb_cgroup_write; > > - /* Add the usage file */ > + /* Add the reservation limit file */ > cft = &h->cgroup_files[1]; > + snprintf(cft->name, MAX_CFTYPE_NAME, "%s.reservation_limit_in_bytes", > + buf); > + cft->private = MEMFILE_PRIVATE(idx, RES_RESERVATION_LIMIT); > + cft->read_u64 = hugetlb_cgroup_read_u64; > + cft->write = hugetlb_cgroup_write; > + > + /* Add the usage file */ > + cft = &h->cgroup_files[2]; > snprintf(cft->name, MAX_CFTYPE_NAME, "%s.usage_in_bytes", buf); > cft->private = MEMFILE_PRIVATE(idx, RES_USAGE); > cft->read_u64 = hugetlb_cgroup_read_u64; > > + /* Add the reservation usage file */ > + cft = &h->cgroup_files[3]; > + snprintf(cft->name, MAX_CFTYPE_NAME, "%s.reservation_usage_in_bytes", > + buf); > + cft->private = MEMFILE_PRIVATE(idx, RES_RESERVATION_USAGE); > + cft->read_u64 = hugetlb_cgroup_read_u64; > + > /* Add the MAX usage file */ > - cft = &h->cgroup_files[2]; > + cft = &h->cgroup_files[4]; > snprintf(cft->name, MAX_CFTYPE_NAME, "%s.max_usage_in_bytes", buf); > cft->private = MEMFILE_PRIVATE(idx, RES_MAX_USAGE); > cft->write = hugetlb_cgroup_reset; > cft->read_u64 = hugetlb_cgroup_read_u64; > > + /* Add the MAX reservation usage file */ > + cft = &h->cgroup_files[5]; > + snprintf(cft->name, MAX_CFTYPE_NAME, > + "%s.reservation_max_usage_in_bytes", buf); > + cft->private = MEMFILE_PRIVATE(idx, RES_RESERVATION_MAX_USAGE); > + cft->write = hugetlb_cgroup_reset; > + cft->read_u64 = hugetlb_cgroup_read_u64; > + > /* Add the failcntfile */ > - cft = &h->cgroup_files[3]; > + cft = &h->cgroup_files[6]; > snprintf(cft->name, MAX_CFTYPE_NAME, "%s.failcnt", buf); > cft->private = MEMFILE_PRIVATE(idx, RES_FAILCNT); > cft->write = hugetlb_cgroup_reset; > cft->read_u64 = hugetlb_cgroup_read_u64; > > + /* Add the reservation failcntfile */ > + cft = &h->cgroup_files[7]; > + snprintf(cft->name, MAX_CFTYPE_NAME, "%s.reservation_failcnt", buf); > + cft->private = MEMFILE_PRIVATE(idx, RES_FAILCNT); > + cft->write = hugetlb_cgroup_reset; > + cft->read_u64 = hugetlb_cgroup_read_u64; > + > /* NULL terminate the last cft */ > - cft = &h->cgroup_files[4]; > + cft = &h->cgroup_files[8]; > memset(cft, 0, sizeof(*cft)); Replace numbers with characters. > > WARN_ON(cgroup_add_legacy_cftypes(&hugetlb_cgrp_subsys, > -- > 2.23.0.rc1.153.gdeed80330f-goog