diff options
-rw-r--r-- | Documentation/cgroups/unified-hierarchy.txt | 18 | ||||
-rw-r--r-- | include/linux/cgroup.h | 9 | ||||
-rw-r--r-- | kernel/cgroup.c | 62 | ||||
-rw-r--r-- | mm/memcontrol.c | 1 |
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 | ||
97 | All controllers which are not bound to other hierarchies are | 97 | All controllers which support the unified hierarchy and are not bound |
98 | automatically bound to unified hierarchy and show up at the root of | 98 | to other hierarchies are automatically bound to unified hierarchy and |
99 | it. Controllers which are enabled only in the root of unified | 99 | show up at the root of it. Controllers which are enabled only in the |
100 | hierarchy can be bound to other hierarchies. This allows mixing | 100 | root of unified hierarchy can be bound to other hierarchies. This |
101 | unified hierarchy with the traditional multiple hierarchies in a fully | 101 | allows mixing unified hierarchy with the traditional multiple |
102 | backward compatible way. | 102 | hierarchies in a fully backward compatible way. |
103 | |||
104 | For development purposes, the following boot parameter makes all | ||
105 | controllers to appear on the unified hierarchy whether supported or | ||
106 | not. | ||
107 | |||
108 | cgroup__DEVEL__legacy_files_on_dfl | ||
103 | 109 | ||
104 | A controller can be moved across hierarchies only after the controller | 110 | A controller can be moved across hierarchies only after the controller |
105 | is no longer referenced in its current hierarchy. Because per-cgroup | 111 | is 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 | ||
591 | char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); | 591 | char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); |
592 | 592 | ||
593 | int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); | ||
593 | int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); | 594 | int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); |
594 | int cgroup_rm_cftypes(struct cftype *cfts); | 595 | int 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 | */ |
150 | static bool cgrp_dfl_root_visible; | 150 | static 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 | */ | ||
156 | static 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 */ |
153 | static const unsigned int cgrp_dfl_root_inhibit_ss_mask = 0 | 159 | static 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 | */ | ||
3215 | int 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 | */ | ||
3198 | int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) | 3232 | int 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 | ||
5342 | static 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 | }, |