diff options
-rw-r--r-- | block/blk-cgroup.c | 8 | ||||
-rw-r--r-- | include/linux/cgroup.h | 15 | ||||
-rw-r--r-- | kernel/cgroup.c | 12 | ||||
-rw-r--r-- | kernel/cgroup_freezer.c | 8 | ||||
-rw-r--r-- | kernel/events/core.c | 7 | ||||
-rw-r--r-- | mm/memcontrol.c | 7 | ||||
-rw-r--r-- | net/core/netprio_cgroup.c | 12 | ||||
-rw-r--r-- | net/sched/cls_cgroup.c | 9 | ||||
-rw-r--r-- | security/device_cgroup.c | 9 |
9 files changed, 85 insertions, 2 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index f3b44a65fc7a..cafcd7431189 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -737,6 +737,14 @@ struct cgroup_subsys blkio_subsys = { | |||
737 | .subsys_id = blkio_subsys_id, | 737 | .subsys_id = blkio_subsys_id, |
738 | .base_cftypes = blkcg_files, | 738 | .base_cftypes = blkcg_files, |
739 | .module = THIS_MODULE, | 739 | .module = THIS_MODULE, |
740 | |||
741 | /* | ||
742 | * blkio subsystem is utterly broken in terms of hierarchy support. | ||
743 | * It treats all cgroups equally regardless of where they're | ||
744 | * located in the hierarchy - all cgroups are treated as if they're | ||
745 | * right below the root. Fix it and remove the following. | ||
746 | */ | ||
747 | .broken_hierarchy = true, | ||
740 | }; | 748 | }; |
741 | EXPORT_SYMBOL_GPL(blkio_subsys); | 749 | EXPORT_SYMBOL_GPL(blkio_subsys); |
742 | 750 | ||
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index df354ae079c1..f8a030ced0c7 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -499,6 +499,21 @@ struct cgroup_subsys { | |||
499 | */ | 499 | */ |
500 | bool __DEPRECATED_clear_css_refs; | 500 | bool __DEPRECATED_clear_css_refs; |
501 | 501 | ||
502 | /* | ||
503 | * If %false, this subsystem is properly hierarchical - | ||
504 | * configuration, resource accounting and restriction on a parent | ||
505 | * cgroup cover those of its children. If %true, hierarchy support | ||
506 | * is broken in some ways - some subsystems ignore hierarchy | ||
507 | * completely while others are only implemented half-way. | ||
508 | * | ||
509 | * It's now disallowed to create nested cgroups if the subsystem is | ||
510 | * broken and cgroup core will emit a warning message on such | ||
511 | * cases. Eventually, all subsystems will be made properly | ||
512 | * hierarchical and this will go away. | ||
513 | */ | ||
514 | bool broken_hierarchy; | ||
515 | bool warned_broken_hierarchy; | ||
516 | |||
502 | #define MAX_CGROUP_TYPE_NAMELEN 32 | 517 | #define MAX_CGROUP_TYPE_NAMELEN 32 |
503 | const char *name; | 518 | const char *name; |
504 | 519 | ||
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 485cc1487ea2..13774b3b39aa 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4076,8 +4076,9 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4076 | set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | 4076 | set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); |
4077 | 4077 | ||
4078 | for_each_subsys(root, ss) { | 4078 | for_each_subsys(root, ss) { |
4079 | struct cgroup_subsys_state *css = ss->create(cgrp); | 4079 | struct cgroup_subsys_state *css; |
4080 | 4080 | ||
4081 | css = ss->create(cgrp); | ||
4081 | if (IS_ERR(css)) { | 4082 | if (IS_ERR(css)) { |
4082 | err = PTR_ERR(css); | 4083 | err = PTR_ERR(css); |
4083 | goto err_destroy; | 4084 | goto err_destroy; |
@@ -4091,6 +4092,15 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4091 | /* At error, ->destroy() callback has to free assigned ID. */ | 4092 | /* At error, ->destroy() callback has to free assigned ID. */ |
4092 | if (clone_children(parent) && ss->post_clone) | 4093 | if (clone_children(parent) && ss->post_clone) |
4093 | ss->post_clone(cgrp); | 4094 | ss->post_clone(cgrp); |
4095 | |||
4096 | if (ss->broken_hierarchy && !ss->warned_broken_hierarchy && | ||
4097 | parent->parent) { | ||
4098 | pr_warning("cgroup: %s (%d) created nested cgroup for controller \"%s\" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.\n", | ||
4099 | current->comm, current->pid, ss->name); | ||
4100 | if (!strcmp(ss->name, "memory")) | ||
4101 | pr_warning("cgroup: \"memory\" requires setting use_hierarchy to 1 on the root.\n"); | ||
4102 | ss->warned_broken_hierarchy = true; | ||
4103 | } | ||
4094 | } | 4104 | } |
4095 | 4105 | ||
4096 | list_add(&cgrp->sibling, &cgrp->parent->children); | 4106 | list_add(&cgrp->sibling, &cgrp->parent->children); |
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index 3649fc6b3eaa..b1724ce98981 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
@@ -373,4 +373,12 @@ struct cgroup_subsys freezer_subsys = { | |||
373 | .can_attach = freezer_can_attach, | 373 | .can_attach = freezer_can_attach, |
374 | .fork = freezer_fork, | 374 | .fork = freezer_fork, |
375 | .base_cftypes = files, | 375 | .base_cftypes = files, |
376 | |||
377 | /* | ||
378 | * freezer subsys doesn't handle hierarchy at all. Frozen state | ||
379 | * should be inherited through the hierarchy - if a parent is | ||
380 | * frozen, all its children should be frozen. Fix it and remove | ||
381 | * the following. | ||
382 | */ | ||
383 | .broken_hierarchy = true, | ||
376 | }; | 384 | }; |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 7b9df353ba1b..deec4e50eb30 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -7503,5 +7503,12 @@ struct cgroup_subsys perf_subsys = { | |||
7503 | .destroy = perf_cgroup_destroy, | 7503 | .destroy = perf_cgroup_destroy, |
7504 | .exit = perf_cgroup_exit, | 7504 | .exit = perf_cgroup_exit, |
7505 | .attach = perf_cgroup_attach, | 7505 | .attach = perf_cgroup_attach, |
7506 | |||
7507 | /* | ||
7508 | * perf_event cgroup doesn't handle nesting correctly. | ||
7509 | * ctx->nr_cgroups adjustments should be propagated through the | ||
7510 | * cgroup hierarchy. Fix it and remove the following. | ||
7511 | */ | ||
7512 | .broken_hierarchy = true, | ||
7506 | }; | 7513 | }; |
7507 | #endif /* CONFIG_CGROUP_PERF */ | 7514 | #endif /* CONFIG_CGROUP_PERF */ |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 795e525afaba..a72f2ffdc3d0 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -4973,6 +4973,13 @@ mem_cgroup_create(struct cgroup *cont) | |||
4973 | } else { | 4973 | } else { |
4974 | res_counter_init(&memcg->res, NULL); | 4974 | res_counter_init(&memcg->res, NULL); |
4975 | res_counter_init(&memcg->memsw, NULL); | 4975 | res_counter_init(&memcg->memsw, NULL); |
4976 | /* | ||
4977 | * Deeper hierachy with use_hierarchy == false doesn't make | ||
4978 | * much sense so let cgroup subsystem know about this | ||
4979 | * unfortunate state in our controller. | ||
4980 | */ | ||
4981 | if (parent && parent != root_mem_cgroup) | ||
4982 | mem_cgroup_subsys.broken_hierarchy = true; | ||
4976 | } | 4983 | } |
4977 | memcg->last_scanned_node = MAX_NUMNODES; | 4984 | memcg->last_scanned_node = MAX_NUMNODES; |
4978 | INIT_LIST_HEAD(&memcg->oom_notify); | 4985 | INIT_LIST_HEAD(&memcg->oom_notify); |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 6bc460c38e4f..39e7e4d3cdb4 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -328,7 +328,17 @@ struct cgroup_subsys net_prio_subsys = { | |||
328 | .attach = net_prio_attach, | 328 | .attach = net_prio_attach, |
329 | .subsys_id = net_prio_subsys_id, | 329 | .subsys_id = net_prio_subsys_id, |
330 | .base_cftypes = ss_files, | 330 | .base_cftypes = ss_files, |
331 | .module = THIS_MODULE | 331 | .module = THIS_MODULE, |
332 | |||
333 | /* | ||
334 | * net_prio has artificial limit on the number of cgroups and | ||
335 | * disallows nesting making it impossible to co-mount it with other | ||
336 | * hierarchical subsystems. Remove the artificially low PRIOIDX_SZ | ||
337 | * limit and properly nest configuration such that children follow | ||
338 | * their parents' configurations by default and are allowed to | ||
339 | * override and remove the following. | ||
340 | */ | ||
341 | .broken_hierarchy = true, | ||
332 | }; | 342 | }; |
333 | 343 | ||
334 | static int netprio_device_event(struct notifier_block *unused, | 344 | static int netprio_device_event(struct notifier_block *unused, |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 67cf90d962f4..4a23ccca6b70 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -80,6 +80,15 @@ struct cgroup_subsys net_cls_subsys = { | |||
80 | .subsys_id = net_cls_subsys_id, | 80 | .subsys_id = net_cls_subsys_id, |
81 | .base_cftypes = ss_files, | 81 | .base_cftypes = ss_files, |
82 | .module = THIS_MODULE, | 82 | .module = THIS_MODULE, |
83 | |||
84 | /* | ||
85 | * While net_cls cgroup has the rudimentary hierarchy support of | ||
86 | * inheriting the parent's classid on cgroup creation, it doesn't | ||
87 | * properly propagates config changes in ancestors to their | ||
88 | * descendents. A child should follow the parent's configuration | ||
89 | * but be allowed to override it. Fix it and remove the following. | ||
90 | */ | ||
91 | .broken_hierarchy = true, | ||
83 | }; | 92 | }; |
84 | 93 | ||
85 | struct cls_cgroup_head { | 94 | struct cls_cgroup_head { |
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 442204cc22d9..4b877a92a7ea 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -457,6 +457,15 @@ struct cgroup_subsys devices_subsys = { | |||
457 | .destroy = devcgroup_destroy, | 457 | .destroy = devcgroup_destroy, |
458 | .subsys_id = devices_subsys_id, | 458 | .subsys_id = devices_subsys_id, |
459 | .base_cftypes = dev_cgroup_files, | 459 | .base_cftypes = dev_cgroup_files, |
460 | |||
461 | /* | ||
462 | * While devices cgroup has the rudimentary hierarchy support which | ||
463 | * checks the parent's restriction, it doesn't properly propagates | ||
464 | * config changes in ancestors to their descendents. A child | ||
465 | * should only be allowed to add more restrictions to the parent's | ||
466 | * configuration. Fix it and remove the following. | ||
467 | */ | ||
468 | .broken_hierarchy = true, | ||
460 | }; | 469 | }; |
461 | 470 | ||
462 | int __devcgroup_inode_permission(struct inode *inode, int mask) | 471 | int __devcgroup_inode_permission(struct inode *inode, int mask) |