Skip to content

Commit e18df28

Browse files
Xiu Jianfengakpm00
authored andcommitted
mm/hugetlb_cgroup: prepare cftypes based on template
Unlike other cgroup subsystems, the hugetlb cgroup does not provide a static array of cftype that explicitly displays the properties, handling functions, etc., of each file. Instead, it dynamically creates the attribute of cftypes based on the hstate during the startup procedure. This reduces the readability of the code. To fix this issue, introduce two templates of cftypes, and rebuild the attributes according to the hstate to make it ready to be added to cgroup framework. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Xiu Jianfeng <[email protected]> Cc: Muchun Song <[email protected]> Cc: Oscar Salvador <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent f79e808 commit e18df28

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

mm/hugetlb_cgroup.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,17 @@
2727
#define MEMFILE_IDX(val) (((val) >> 16) & 0xffff)
2828
#define MEMFILE_ATTR(val) ((val) & 0xffff)
2929

30+
/* Use t->m[0] to encode the offset */
31+
#define MEMFILE_OFFSET(t, m0) (((offsetof(t, m0) << 16) | sizeof_field(t, m0)))
32+
#define MEMFILE_OFFSET0(val) (((val) >> 16) & 0xffff)
33+
#define MEMFILE_FIELD_SIZE(val) ((val) & 0xffff)
34+
35+
#define DFL_TMPL_SIZE ARRAY_SIZE(hugetlb_dfl_tmpl)
36+
#define LEGACY_TMPL_SIZE ARRAY_SIZE(hugetlb_legacy_tmpl)
37+
3038
static struct hugetlb_cgroup *root_h_cgroup __read_mostly;
39+
static struct cftype *dfl_files;
40+
static struct cftype *legacy_files;
3141

3242
static inline struct page_counter *
3343
__hugetlb_cgroup_counter_from_cgroup(struct hugetlb_cgroup *h_cg, int idx,
@@ -702,12 +712,142 @@ static int hugetlb_events_local_show(struct seq_file *seq, void *v)
702712
return __hugetlb_events_show(seq, true);
703713
}
704714

715+
static struct cftype hugetlb_dfl_tmpl[] = {
716+
{
717+
.name = "max",
718+
.private = RES_LIMIT,
719+
.seq_show = hugetlb_cgroup_read_u64_max,
720+
.write = hugetlb_cgroup_write_dfl,
721+
.flags = CFTYPE_NOT_ON_ROOT,
722+
},
723+
{
724+
.name = "rsvd.max",
725+
.private = RES_RSVD_LIMIT,
726+
.seq_show = hugetlb_cgroup_read_u64_max,
727+
.write = hugetlb_cgroup_write_dfl,
728+
.flags = CFTYPE_NOT_ON_ROOT,
729+
},
730+
{
731+
.name = "current",
732+
.private = RES_USAGE,
733+
.seq_show = hugetlb_cgroup_read_u64_max,
734+
.flags = CFTYPE_NOT_ON_ROOT,
735+
},
736+
{
737+
.name = "rsvd.current",
738+
.private = RES_RSVD_USAGE,
739+
.seq_show = hugetlb_cgroup_read_u64_max,
740+
.flags = CFTYPE_NOT_ON_ROOT,
741+
},
742+
{
743+
.name = "events",
744+
.seq_show = hugetlb_events_show,
745+
.file_offset = MEMFILE_OFFSET(struct hugetlb_cgroup, events_file[0]),
746+
.flags = CFTYPE_NOT_ON_ROOT,
747+
},
748+
{
749+
.name = "events.local",
750+
.seq_show = hugetlb_events_local_show,
751+
.file_offset = MEMFILE_OFFSET(struct hugetlb_cgroup, events_local_file[0]),
752+
.flags = CFTYPE_NOT_ON_ROOT,
753+
},
754+
{
755+
.name = "numa_stat",
756+
.seq_show = hugetlb_cgroup_read_numa_stat,
757+
.flags = CFTYPE_NOT_ON_ROOT,
758+
},
759+
/* don't need terminator here */
760+
};
761+
762+
static struct cftype hugetlb_legacy_tmpl[] = {
763+
{
764+
.name = "limit_in_bytes",
765+
.private = RES_LIMIT,
766+
.read_u64 = hugetlb_cgroup_read_u64,
767+
.write = hugetlb_cgroup_write_legacy,
768+
},
769+
{
770+
.name = "rsvd.limit_in_bytes",
771+
.private = RES_RSVD_LIMIT,
772+
.read_u64 = hugetlb_cgroup_read_u64,
773+
.write = hugetlb_cgroup_write_legacy,
774+
},
775+
{
776+
.name = "usage_in_bytes",
777+
.private = RES_USAGE,
778+
.read_u64 = hugetlb_cgroup_read_u64,
779+
},
780+
{
781+
.name = "rsvd.usage_in_bytes",
782+
.private = RES_RSVD_USAGE,
783+
.read_u64 = hugetlb_cgroup_read_u64,
784+
},
785+
{
786+
.name = "max_usage_in_bytes",
787+
.private = RES_MAX_USAGE,
788+
.write = hugetlb_cgroup_reset,
789+
.read_u64 = hugetlb_cgroup_read_u64,
790+
},
791+
{
792+
.name = "rsvd.max_usage_in_bytes",
793+
.private = RES_RSVD_MAX_USAGE,
794+
.write = hugetlb_cgroup_reset,
795+
.read_u64 = hugetlb_cgroup_read_u64,
796+
},
797+
{
798+
.name = "failcnt",
799+
.private = RES_FAILCNT,
800+
.write = hugetlb_cgroup_reset,
801+
.read_u64 = hugetlb_cgroup_read_u64,
802+
},
803+
{
804+
.name = "rsvd.failcnt",
805+
.private = RES_RSVD_FAILCNT,
806+
.write = hugetlb_cgroup_reset,
807+
.read_u64 = hugetlb_cgroup_read_u64,
808+
},
809+
{
810+
.name = "numa_stat",
811+
.seq_show = hugetlb_cgroup_read_numa_stat,
812+
},
813+
/* don't need terminator here */
814+
};
815+
816+
static void __init
817+
hugetlb_cgroup_cfttypes_init(struct hstate *h, struct cftype *cft,
818+
struct cftype *tmpl, int tmpl_size)
819+
{
820+
char buf[32];
821+
int i, idx = hstate_index(h);
822+
823+
/* format the size */
824+
mem_fmt(buf, sizeof(buf), huge_page_size(h));
825+
826+
for (i = 0; i < tmpl_size; cft++, tmpl++, i++) {
827+
*cft = *tmpl;
828+
/* rebuild the name */
829+
snprintf(cft->name, MAX_CFTYPE_NAME, "%s.%s", buf, tmpl->name);
830+
/* rebuild the private */
831+
cft->private = MEMFILE_PRIVATE(idx, tmpl->private);
832+
/* rebuild the file_offset */
833+
if (tmpl->file_offset) {
834+
unsigned int offset = tmpl->file_offset;
835+
836+
cft->file_offset = MEMFILE_OFFSET0(offset) +
837+
MEMFILE_FIELD_SIZE(offset) * idx;
838+
}
839+
}
840+
}
841+
705842
static void __init __hugetlb_cgroup_file_dfl_init(int idx)
706843
{
707844
char buf[32];
708845
struct cftype *cft;
709846
struct hstate *h = &hstates[idx];
710847

848+
hugetlb_cgroup_cfttypes_init(h, dfl_files + idx * DFL_TMPL_SIZE,
849+
hugetlb_dfl_tmpl, DFL_TMPL_SIZE);
850+
711851
/* format the size */
712852
mem_fmt(buf, sizeof(buf), huge_page_size(h));
713853

@@ -779,6 +919,9 @@ static void __init __hugetlb_cgroup_file_legacy_init(int idx)
779919
struct cftype *cft;
780920
struct hstate *h = &hstates[idx];
781921

922+
hugetlb_cgroup_cfttypes_init(h, legacy_files + idx * LEGACY_TMPL_SIZE,
923+
hugetlb_legacy_tmpl, LEGACY_TMPL_SIZE);
924+
782925
/* format the size */
783926
mem_fmt(buf, sizeof(buf), huge_page_size(h));
784927

@@ -856,10 +999,23 @@ static void __init __hugetlb_cgroup_file_init(int idx)
856999
__hugetlb_cgroup_file_legacy_init(idx);
8571000
}
8581001

1002+
static void __init __hugetlb_cgroup_file_pre_init(void)
1003+
{
1004+
int cft_count;
1005+
1006+
cft_count = hugetlb_max_hstate * DFL_TMPL_SIZE + 1; /* add terminator */
1007+
dfl_files = kcalloc(cft_count, sizeof(struct cftype), GFP_KERNEL);
1008+
BUG_ON(!dfl_files);
1009+
cft_count = hugetlb_max_hstate * LEGACY_TMPL_SIZE + 1; /* add terminator */
1010+
legacy_files = kcalloc(cft_count, sizeof(struct cftype), GFP_KERNEL);
1011+
BUG_ON(!legacy_files);
1012+
}
1013+
8591014
void __init hugetlb_cgroup_file_init(void)
8601015
{
8611016
struct hstate *h;
8621017

1018+
__hugetlb_cgroup_file_pre_init();
8631019
for_each_hstate(h)
8641020
__hugetlb_cgroup_file_init(hstate_index(h));
8651021
}

0 commit comments

Comments
 (0)