diff options
| author | Tejun Heo <tj@kernel.org> | 2014-03-19 10:23:55 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2014-03-19 10:23:55 -0400 |
| commit | a2dd424750807f83632a2a70293961086fd8f870 (patch) | |
| tree | 75f55e64a9ad9a4babf4c7effcaf75cf327dd6c8 | |
| parent | 4d3bb511b5f9980fc3e9ae5939ebc475b231d3fc (diff) | |
cgroup: make cgrp_dfl_root mountable
cgrp_dfl_root will be used as the default unified hierarchy. This
patch makes cgrp_dfl_root mountable by making the following changes.
* cgroup_init_early() now initializes cgrp_dfl_root w/
CGRP_ROOT_SANE_BEHAVIOR. The default hierarchy is always sane.
* parse_cgroupfs_options() and cgroup_mount() are updated such that
cgrp_dfl_root is mounted if sane_behavior is specified w/o any
subsystems.
* rebind_subsystems() now populates the root directory of
cgrp_dfl_root. Note that the function still guarantees success of
rebinding subsystems to cgrp_dfl_root. If populating fails while
rebinding to cgrp_dfl_root, it whines but ignores the error.
* For backward compatibility, the default hierarchy shows up in
/proc/$PID/cgroup only after it's explicitly mounted so that
userland which doesn't make use of it doesn't see any change.
* "current_css_set_cg_links" file of debug cgroup now treats the
default hierarchy the same as other hierarchies. This is visible to
userland. Given that it's for debug controller, this should be
fine.
* While at it, implement cgroup_on_dfl() which tests whether a give
cgroup is on the default hierarchy or not.
The above changes make cgrp_dfl_root mostly equivalent to other
controllers but the actual unified hierarchy behaviors are not
implemented yet. Let's plug child cgroup creation in cgrp_dfl_root
from create_cgroup() for now.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
| -rw-r--r-- | include/linux/cgroup.h | 10 | ||||
| -rw-r--r-- | kernel/cgroup.c | 94 |
2 files changed, 71 insertions, 33 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 79993ac066c5..7e9fa505b7bb 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
| @@ -250,6 +250,9 @@ enum { | |||
| 250 | * | 250 | * |
| 251 | * - "cgroup.clone_children" is removed. | 251 | * - "cgroup.clone_children" is removed. |
| 252 | * | 252 | * |
| 253 | * - If mount is requested with sane_behavior but without any | ||
| 254 | * subsystem, the default unified hierarchy is mounted. | ||
| 255 | * | ||
| 253 | * - cpuset: tasks will be kept in empty cpusets when hotplug happens | 256 | * - cpuset: tasks will be kept in empty cpusets when hotplug happens |
| 254 | * and take masks of ancestors with non-empty cpus/mems, instead of | 257 | * and take masks of ancestors with non-empty cpus/mems, instead of |
| 255 | * being moved to an ancestor. | 258 | * being moved to an ancestor. |
| @@ -468,6 +471,13 @@ struct cftype { | |||
| 468 | #endif | 471 | #endif |
| 469 | }; | 472 | }; |
| 470 | 473 | ||
| 474 | extern struct cgroup_root cgrp_dfl_root; | ||
| 475 | |||
| 476 | static inline bool cgroup_on_dfl(const struct cgroup *cgrp) | ||
| 477 | { | ||
| 478 | return cgrp->root == &cgrp_dfl_root; | ||
| 479 | } | ||
| 480 | |||
| 471 | /* | 481 | /* |
| 472 | * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This | 482 | * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This |
| 473 | * function can be called as long as @cgrp is accessible. | 483 | * function can be called as long as @cgrp is accessible. |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f5754910e80b..69b4939e9f6d 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -142,7 +142,13 @@ static const char *cgroup_subsys_name[] = { | |||
| 142 | * unattached - it never has more than a single cgroup, and all tasks are | 142 | * unattached - it never has more than a single cgroup, and all tasks are |
| 143 | * part of that cgroup. | 143 | * part of that cgroup. |
| 144 | */ | 144 | */ |
| 145 | static struct cgroup_root cgrp_dfl_root; | 145 | struct cgroup_root cgrp_dfl_root; |
| 146 | |||
| 147 | /* | ||
| 148 | * The default hierarchy always exists but is hidden until mounted for the | ||
| 149 | * first time. This is for backward compatibility. | ||
| 150 | */ | ||
| 151 | static bool cgrp_dfl_root_visible; | ||
| 146 | 152 | ||
| 147 | /* The list of hierarchy roots */ | 153 | /* The list of hierarchy roots */ |
| 148 | 154 | ||
| @@ -999,10 +1005,22 @@ static int rebind_subsystems(struct cgroup_root *dst_root, | |||
| 999 | return -EBUSY; | 1005 | return -EBUSY; |
| 1000 | } | 1006 | } |
| 1001 | 1007 | ||
| 1002 | if (dst_root != &cgrp_dfl_root) { | 1008 | ret = cgroup_populate_dir(&dst_root->cgrp, ss_mask); |
| 1003 | ret = cgroup_populate_dir(&dst_root->cgrp, ss_mask); | 1009 | if (ret) { |
| 1004 | if (ret) | 1010 | if (dst_root != &cgrp_dfl_root) |
| 1005 | return ret; | 1011 | return ret; |
| 1012 | |||
| 1013 | /* | ||
| 1014 | * Rebinding back to the default root is not allowed to | ||
| 1015 | * fail. Using both default and non-default roots should | ||
| 1016 | * be rare. Moving subsystems back and forth even more so. | ||
| 1017 | * Just warn about it and continue. | ||
| 1018 | */ | ||
| 1019 | if (cgrp_dfl_root_visible) { | ||
| 1020 | pr_warning("cgroup: failed to create files (%d) while rebinding 0x%lx to default root\n", | ||
| 1021 | ret, ss_mask); | ||
| 1022 | pr_warning("cgroup: you may retry by moving them to a different hierarchy and unbinding\n"); | ||
| 1023 | } | ||
| 1006 | } | 1024 | } |
| 1007 | 1025 | ||
| 1008 | /* | 1026 | /* |
| @@ -1011,7 +1029,7 @@ static int rebind_subsystems(struct cgroup_root *dst_root, | |||
| 1011 | */ | 1029 | */ |
| 1012 | mutex_unlock(&cgroup_mutex); | 1030 | mutex_unlock(&cgroup_mutex); |
| 1013 | for_each_subsys(ss, ssid) | 1031 | for_each_subsys(ss, ssid) |
| 1014 | if ((ss_mask & (1 << ssid)) && ss->root != &cgrp_dfl_root) | 1032 | if (ss_mask & (1 << ssid)) |
| 1015 | cgroup_clear_dir(&ss->root->cgrp, 1 << ssid); | 1033 | cgroup_clear_dir(&ss->root->cgrp, 1 << ssid); |
| 1016 | mutex_lock(&cgroup_mutex); | 1034 | mutex_lock(&cgroup_mutex); |
| 1017 | 1035 | ||
| @@ -1039,8 +1057,7 @@ static int rebind_subsystems(struct cgroup_root *dst_root, | |||
| 1039 | ss->bind(css); | 1057 | ss->bind(css); |
| 1040 | } | 1058 | } |
| 1041 | 1059 | ||
| 1042 | if (dst_root != &cgrp_dfl_root) | 1060 | kernfs_activate(dst_root->cgrp.kn); |
| 1043 | kernfs_activate(dst_root->cgrp.kn); | ||
| 1044 | return 0; | 1061 | return 0; |
| 1045 | } | 1062 | } |
| 1046 | 1063 | ||
| @@ -1190,16 +1207,6 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
| 1190 | return -ENOENT; | 1207 | return -ENOENT; |
| 1191 | } | 1208 | } |
| 1192 | 1209 | ||
| 1193 | /* | ||
| 1194 | * If the 'all' option was specified select all the subsystems, | ||
| 1195 | * otherwise if 'none', 'name=' and a subsystem name options | ||
| 1196 | * were not specified, let's default to 'all' | ||
| 1197 | */ | ||
| 1198 | if (all_ss || (!one_ss && !opts->none && !opts->name)) | ||
| 1199 | for_each_subsys(ss, i) | ||
| 1200 | if (!ss->disabled) | ||
| 1201 | set_bit(i, &opts->subsys_mask); | ||
| 1202 | |||
| 1203 | /* Consistency checks */ | 1210 | /* Consistency checks */ |
| 1204 | 1211 | ||
| 1205 | if (opts->flags & CGRP_ROOT_SANE_BEHAVIOR) { | 1212 | if (opts->flags & CGRP_ROOT_SANE_BEHAVIOR) { |
| @@ -1211,6 +1218,23 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
| 1211 | pr_err("cgroup: sane_behavior: noprefix, xattr, clone_children, release_agent and name are not allowed\n"); | 1218 | pr_err("cgroup: sane_behavior: noprefix, xattr, clone_children, release_agent and name are not allowed\n"); |
| 1212 | return -EINVAL; | 1219 | return -EINVAL; |
| 1213 | } | 1220 | } |
| 1221 | } else { | ||
| 1222 | /* | ||
| 1223 | * If the 'all' option was specified select all the | ||
| 1224 | * subsystems, otherwise if 'none', 'name=' and a subsystem | ||
| 1225 | * name options were not specified, let's default to 'all' | ||
| 1226 | */ | ||
| 1227 | if (all_ss || (!one_ss && !opts->none && !opts->name)) | ||
| 1228 | for_each_subsys(ss, i) | ||
| 1229 | if (!ss->disabled) | ||
| 1230 | set_bit(i, &opts->subsys_mask); | ||
| 1231 | |||
| 1232 | /* | ||
| 1233 | * We either have to specify by name or by subsystems. (So | ||
| 1234 | * all empty hierarchies must have a name). | ||
| 1235 | */ | ||
| 1236 | if (!opts->subsys_mask && !opts->name) | ||
| 1237 | return -EINVAL; | ||
| 1214 | } | 1238 | } |
| 1215 | 1239 | ||
| 1216 | /* | 1240 | /* |
| @@ -1226,13 +1250,6 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
| 1226 | if (opts->subsys_mask && opts->none) | 1250 | if (opts->subsys_mask && opts->none) |
| 1227 | return -EINVAL; | 1251 | return -EINVAL; |
| 1228 | 1252 | ||
| 1229 | /* | ||
| 1230 | * We either have to specify by name or by subsystems. (So all | ||
| 1231 | * empty hierarchies must have a name). | ||
| 1232 | */ | ||
| 1233 | if (!opts->subsys_mask && !opts->name) | ||
| 1234 | return -EINVAL; | ||
| 1235 | |||
| 1236 | return 0; | 1253 | return 0; |
| 1237 | } | 1254 | } |
| 1238 | 1255 | ||
| @@ -1487,6 +1504,14 @@ retry: | |||
| 1487 | goto out_unlock; | 1504 | goto out_unlock; |
| 1488 | 1505 | ||
| 1489 | /* look for a matching existing root */ | 1506 | /* look for a matching existing root */ |
| 1507 | if (!opts.subsys_mask && !opts.none && !opts.name) { | ||
| 1508 | cgrp_dfl_root_visible = true; | ||
| 1509 | root = &cgrp_dfl_root; | ||
| 1510 | cgroup_get(&root->cgrp); | ||
| 1511 | ret = 0; | ||
| 1512 | goto out_unlock; | ||
| 1513 | } | ||
| 1514 | |||
| 1490 | for_each_root(root) { | 1515 | for_each_root(root) { |
| 1491 | bool name_match = false; | 1516 | bool name_match = false; |
| 1492 | 1517 | ||
| @@ -3622,6 +3647,13 @@ static long cgroup_create(struct cgroup *parent, const char *name, | |||
| 3622 | struct cgroup_subsys *ss; | 3647 | struct cgroup_subsys *ss; |
| 3623 | struct kernfs_node *kn; | 3648 | struct kernfs_node *kn; |
| 3624 | 3649 | ||
| 3650 | /* | ||
| 3651 | * XXX: The default hierarchy isn't fully implemented yet. Block | ||
| 3652 | * !root cgroup creation on it for now. | ||
| 3653 | */ | ||
| 3654 | if (root == &cgrp_dfl_root) | ||
| 3655 | return -EINVAL; | ||
| 3656 | |||
| 3625 | /* allocate the cgroup and its ID, 0 is reserved for the root */ | 3657 | /* allocate the cgroup and its ID, 0 is reserved for the root */ |
| 3626 | cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); | 3658 | cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); |
| 3627 | if (!cgrp) | 3659 | if (!cgrp) |
| @@ -4061,7 +4093,8 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) | |||
| 4061 | */ | 4093 | */ |
| 4062 | int __init cgroup_init_early(void) | 4094 | int __init cgroup_init_early(void) |
| 4063 | { | 4095 | { |
| 4064 | static struct cgroup_sb_opts __initdata opts = { }; | 4096 | static struct cgroup_sb_opts __initdata opts = |
| 4097 | { .flags = CGRP_ROOT_SANE_BEHAVIOR }; | ||
| 4065 | struct cgroup_subsys *ss; | 4098 | struct cgroup_subsys *ss; |
| 4066 | int i; | 4099 | int i; |
| 4067 | 4100 | ||
| @@ -4198,7 +4231,7 @@ int proc_cgroup_show(struct seq_file *m, void *v) | |||
| 4198 | struct cgroup *cgrp; | 4231 | struct cgroup *cgrp; |
| 4199 | int ssid, count = 0; | 4232 | int ssid, count = 0; |
| 4200 | 4233 | ||
| 4201 | if (root == &cgrp_dfl_root) | 4234 | if (root == &cgrp_dfl_root && !cgrp_dfl_root_visible) |
| 4202 | continue; | 4235 | continue; |
| 4203 | 4236 | ||
| 4204 | seq_printf(m, "%d:", root->hierarchy_id); | 4237 | seq_printf(m, "%d:", root->hierarchy_id); |
| @@ -4631,15 +4664,10 @@ static int current_css_set_cg_links_read(struct seq_file *seq, void *v) | |||
| 4631 | cset = rcu_dereference(current->cgroups); | 4664 | cset = rcu_dereference(current->cgroups); |
| 4632 | list_for_each_entry(link, &cset->cgrp_links, cgrp_link) { | 4665 | list_for_each_entry(link, &cset->cgrp_links, cgrp_link) { |
| 4633 | struct cgroup *c = link->cgrp; | 4666 | struct cgroup *c = link->cgrp; |
| 4634 | const char *name = "?"; | ||
| 4635 | |||
| 4636 | if (c != &cgrp_dfl_root.cgrp) { | ||
| 4637 | cgroup_name(c, name_buf, NAME_MAX + 1); | ||
| 4638 | name = name_buf; | ||
| 4639 | } | ||
| 4640 | 4667 | ||
| 4668 | cgroup_name(c, name_buf, NAME_MAX + 1); | ||
| 4641 | seq_printf(seq, "Root %d group %s\n", | 4669 | seq_printf(seq, "Root %d group %s\n", |
| 4642 | c->root->hierarchy_id, name); | 4670 | c->root->hierarchy_id, name_buf); |
| 4643 | } | 4671 | } |
| 4644 | rcu_read_unlock(); | 4672 | rcu_read_unlock(); |
| 4645 | up_read(&css_set_rwsem); | 4673 | up_read(&css_set_rwsem); |
