aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-07-08 18:02:57 -0400
committerTejun Heo <tj@kernel.org>2014-07-08 18:02:57 -0400
commitaf0ba6789c8e43518635606d0af1ff475ba7471a (patch)
treee191c511bc1102149d4e44b196ec96691179f67f /kernel/cgroup.c
parentb4536f0cab2b18414e26101a2b9d484c5cbea0c0 (diff)
cgroup: implement cgroup_subsys->depends_on
Currently, the blkio subsystem attributes all of writeback IOs to the root. One of the issues is that there's no way to tell who originated a writeback IO from block layer. Those IOs are usually issued asynchronously from a task which didn't have anything to do with actually generating the dirty pages. The memory subsystem, when enabled, already keeps track of the ownership of each dirty page and it's desirable for blkio to piggyback instead of adding its own per-page tag. blkio piggybacking on memory is an implementation detail which preferably should be handled automatically without requiring explicit userland action. To achieve that, this patch implements cgroup_subsys->depends_on which contains the mask of subsystems which should be enabled together when the subsystem is enabled. The previous patches already implemented the support for enabled but invisible subsystems and cgroup_subsys->depends_on can be easily implemented by updating cgroup_refresh_child_subsys_mask() so that it calculates cgroup->child_subsys_mask considering cgroup_subsys->depends_on of the explicitly enabled subsystems. Documentation/cgroups/unified-hierarchy.txt is updated to explain that subsystems may not become immediately available after being unused from userland and that dependency could be a factor in it. As subsystems may already keep residual references, this doesn't significantly change how subsystem rebinding can be used. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 3a6b77d7ba4a..cd02e99d5d3b 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1037,9 +1037,56 @@ static void cgroup_put(struct cgroup *cgrp)
1037 css_put(&cgrp->self); 1037 css_put(&cgrp->self);
1038} 1038}
1039 1039
1040/**
1041 * cgroup_refresh_child_subsys_mask - update child_subsys_mask
1042 * @cgrp: the target cgroup
1043 *
1044 * On the default hierarchy, a subsystem may request other subsystems to be
1045 * enabled together through its ->depends_on mask. In such cases, more
1046 * subsystems than specified in "cgroup.subtree_control" may be enabled.
1047 *
1048 * This function determines which subsystems need to be enabled given the
1049 * current @cgrp->subtree_control and records it in
1050 * @cgrp->child_subsys_mask. The resulting mask is always a superset of
1051 * @cgrp->subtree_control and follows the usual hierarchy rules.
1052 */
1040static void cgroup_refresh_child_subsys_mask(struct cgroup *cgrp) 1053static void cgroup_refresh_child_subsys_mask(struct cgroup *cgrp)
1041{ 1054{
1042 cgrp->child_subsys_mask = cgrp->subtree_control; 1055 struct cgroup *parent = cgroup_parent(cgrp);
1056 unsigned int cur_ss_mask = cgrp->subtree_control;
1057 struct cgroup_subsys *ss;
1058 int ssid;
1059
1060 lockdep_assert_held(&cgroup_mutex);
1061
1062 if (!cgroup_on_dfl(cgrp)) {
1063 cgrp->child_subsys_mask = cur_ss_mask;
1064 return;
1065 }
1066
1067 while (true) {
1068 unsigned int new_ss_mask = cur_ss_mask;
1069
1070 for_each_subsys(ss, ssid)
1071 if (cur_ss_mask & (1 << ssid))
1072 new_ss_mask |= ss->depends_on;
1073
1074 /*
1075 * Mask out subsystems which aren't available. This can
1076 * happen only if some depended-upon subsystems were bound
1077 * to non-default hierarchies.
1078 */
1079 if (parent)
1080 new_ss_mask &= parent->child_subsys_mask;
1081 else
1082 new_ss_mask &= cgrp->root->subsys_mask;
1083
1084 if (new_ss_mask == cur_ss_mask)
1085 break;
1086 cur_ss_mask = new_ss_mask;
1087 }
1088
1089 cgrp->child_subsys_mask = cur_ss_mask;
1043} 1090}
1044 1091
1045/** 1092/**