aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-cgroup.c8
-rw-r--r--include/linux/cgroup.h15
-rw-r--r--kernel/cgroup.c12
-rw-r--r--kernel/cgroup_freezer.c8
-rw-r--r--kernel/events/core.c7
-rw-r--r--mm/memcontrol.c7
-rw-r--r--net/core/netprio_cgroup.c12
-rw-r--r--net/sched/cls_cgroup.c9
-rw-r--r--security/device_cgroup.c9
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};
741EXPORT_SYMBOL_GPL(blkio_subsys); 749EXPORT_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
334static int netprio_device_event(struct notifier_block *unused, 344static 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
85struct cls_cgroup_head { 94struct 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
462int __devcgroup_inode_permission(struct inode *inode, int mask) 471int __devcgroup_inode_permission(struct inode *inode, int mask)