aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/cgroups/unified-hierarchy.txt18
-rw-r--r--include/linux/cgroup.h9
-rw-r--r--kernel/cgroup.c62
-rw-r--r--mm/memcontrol.c1
4 files changed, 78 insertions, 12 deletions
diff --git a/Documentation/cgroups/unified-hierarchy.txt b/Documentation/cgroups/unified-hierarchy.txt
index a7a2205539a7..4f4563277864 100644
--- a/Documentation/cgroups/unified-hierarchy.txt
+++ b/Documentation/cgroups/unified-hierarchy.txt
@@ -94,12 +94,18 @@ change soon.
94 94
95 mount -t cgroup -o __DEVEL__sane_behavior cgroup $MOUNT_POINT 95 mount -t cgroup -o __DEVEL__sane_behavior cgroup $MOUNT_POINT
96 96
97All controllers which are not bound to other hierarchies are 97All controllers which support the unified hierarchy and are not bound
98automatically bound to unified hierarchy and show up at the root of 98to other hierarchies are automatically bound to unified hierarchy and
99it. Controllers which are enabled only in the root of unified 99show up at the root of it. Controllers which are enabled only in the
100hierarchy can be bound to other hierarchies. This allows mixing 100root of unified hierarchy can be bound to other hierarchies. This
101unified hierarchy with the traditional multiple hierarchies in a fully 101allows mixing unified hierarchy with the traditional multiple
102backward compatible way. 102hierarchies in a fully backward compatible way.
103
104For development purposes, the following boot parameter makes all
105controllers to appear on the unified hierarchy whether supported or
106not.
107
108 cgroup__DEVEL__legacy_files_on_dfl
103 109
104A controller can be moved across hierarchies only after the controller 110A controller can be moved across hierarchies only after the controller
105is no longer referenced in its current hierarchy. Because per-cgroup 111is no longer referenced in its current hierarchy. Because per-cgroup
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index f5f0feef2701..9f76236ac158 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -590,6 +590,7 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp)
590 590
591char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); 591char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
592 592
593int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
593int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); 594int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
594int cgroup_rm_cftypes(struct cftype *cfts); 595int cgroup_rm_cftypes(struct cftype *cfts);
595 596
@@ -671,8 +672,12 @@ struct cgroup_subsys {
671 */ 672 */
672 struct list_head cfts; 673 struct list_head cfts;
673 674
674 /* base cftypes, automatically registered with subsys itself */ 675 /*
675 struct cftype *legacy_cftypes; /* used on the legacy hierarchies */ 676 * Base cftypes which are automatically registered. The two can
677 * point to the same array.
678 */
679 struct cftype *dfl_cftypes; /* for the default hierarchy */
680 struct cftype *legacy_cftypes; /* for the legacy hierarchies */
676 681
677 /* 682 /*
678 * A subsystem may depend on other subsystems. When such subsystem 683 * A subsystem may depend on other subsystems. When such subsystem
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index c275aa439a6f..374ebdf74f35 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -149,6 +149,12 @@ struct cgroup_root cgrp_dfl_root;
149 */ 149 */
150static bool cgrp_dfl_root_visible; 150static bool cgrp_dfl_root_visible;
151 151
152/*
153 * Set by the boot param of the same name and makes subsystems with NULL
154 * ->dfl_files to use ->legacy_files on the default hierarchy.
155 */
156static bool cgroup_legacy_files_on_dfl;
157
152/* some controllers are not supported in the default hierarchy */ 158/* some controllers are not supported in the default hierarchy */
153static const unsigned int cgrp_dfl_root_inhibit_ss_mask = 0 159static const unsigned int cgrp_dfl_root_inhibit_ss_mask = 0
154#ifdef CONFIG_CGROUP_DEBUG 160#ifdef CONFIG_CGROUP_DEBUG
@@ -3085,6 +3091,9 @@ static void cgroup_exit_cftypes(struct cftype *cfts)
3085 kfree(cft->kf_ops); 3091 kfree(cft->kf_ops);
3086 cft->kf_ops = NULL; 3092 cft->kf_ops = NULL;
3087 cft->ss = NULL; 3093 cft->ss = NULL;
3094
3095 /* revert flags set by cgroup core while adding @cfts */
3096 cft->flags &= ~(CFTYPE_ONLY_ON_DFL | CFTYPE_INSANE);
3088 } 3097 }
3089} 3098}
3090 3099
@@ -3195,8 +3204,37 @@ static int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
3195 return ret; 3204 return ret;
3196} 3205}
3197 3206
3207/**
3208 * cgroup_add_dfl_cftypes - add an array of cftypes for default hierarchy
3209 * @ss: target cgroup subsystem
3210 * @cfts: zero-length name terminated array of cftypes
3211 *
3212 * Similar to cgroup_add_cftypes() but the added files are only used for
3213 * the default hierarchy.
3214 */
3215int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
3216{
3217 struct cftype *cft;
3218
3219 for (cft = cfts; cft && cft->name[0] != '\0'; cft++)
3220 cft->flags |= CFTYPE_ONLY_ON_DFL;
3221 return cgroup_add_cftypes(ss, cfts);
3222}
3223
3224/**
3225 * cgroup_add_legacy_cftypes - add an array of cftypes for legacy hierarchies
3226 * @ss: target cgroup subsystem
3227 * @cfts: zero-length name terminated array of cftypes
3228 *
3229 * Similar to cgroup_add_cftypes() but the added files are only used for
3230 * the legacy hierarchies.
3231 */
3198int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) 3232int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
3199{ 3233{
3234 struct cftype *cft;
3235
3236 for (cft = cfts; cft && cft->name[0] != '\0'; cft++)
3237 cft->flags |= CFTYPE_INSANE;
3200 return cgroup_add_cftypes(ss, cfts); 3238 return cgroup_add_cftypes(ss, cfts);
3201} 3239}
3202 3240
@@ -4893,9 +4931,19 @@ int __init cgroup_init(void)
4893 * disabled flag and cftype registration needs kmalloc, 4931 * disabled flag and cftype registration needs kmalloc,
4894 * both of which aren't available during early_init. 4932 * both of which aren't available during early_init.
4895 */ 4933 */
4896 if (!ss->disabled) { 4934 if (ss->disabled)
4897 cgrp_dfl_root.subsys_mask |= 1 << ss->id; 4935 continue;
4898 WARN_ON(cgroup_add_cftypes(ss, ss->legacy_cftypes)); 4936
4937 cgrp_dfl_root.subsys_mask |= 1 << ss->id;
4938
4939 if (cgroup_legacy_files_on_dfl && !ss->dfl_cftypes)
4940 ss->dfl_cftypes = ss->legacy_cftypes;
4941
4942 if (ss->dfl_cftypes == ss->legacy_cftypes) {
4943 WARN_ON(cgroup_add_cftypes(ss, ss->dfl_cftypes));
4944 } else {
4945 WARN_ON(cgroup_add_dfl_cftypes(ss, ss->dfl_cftypes));
4946 WARN_ON(cgroup_add_legacy_cftypes(ss, ss->legacy_cftypes));
4899 } 4947 }
4900 } 4948 }
4901 4949
@@ -5291,6 +5339,14 @@ static int __init cgroup_disable(char *str)
5291} 5339}
5292__setup("cgroup_disable=", cgroup_disable); 5340__setup("cgroup_disable=", cgroup_disable);
5293 5341
5342static int __init cgroup_set_legacy_files_on_dfl(char *str)
5343{
5344 printk("cgroup: using legacy files on the default hierarchy\n");
5345 cgroup_legacy_files_on_dfl = true;
5346 return 0;
5347}
5348__setup("cgroup__DEVEL__legacy_files_on_dfl", cgroup_set_legacy_files_on_dfl);
5349
5294/** 5350/**
5295 * css_tryget_online_from_dir - get corresponding css from a cgroup dentry 5351 * css_tryget_online_from_dir - get corresponding css from a cgroup dentry
5296 * @dentry: directory dentry of interest 5352 * @dentry: directory dentry of interest
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index b6b3c6fea509..45c10c6fc3ce 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6003,7 +6003,6 @@ static struct cftype mem_cgroup_files[] = {
6003 }, 6003 },
6004 { 6004 {
6005 .name = "use_hierarchy", 6005 .name = "use_hierarchy",
6006 .flags = CFTYPE_INSANE,
6007 .write_u64 = mem_cgroup_hierarchy_write, 6006 .write_u64 = mem_cgroup_hierarchy_write,
6008 .read_u64 = mem_cgroup_hierarchy_read, 6007 .read_u64 = mem_cgroup_hierarchy_read,
6009 }, 6008 },