diff options
author | Tejun Heo <tj@kernel.org> | 2012-11-09 12:12:29 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-11-09 12:12:29 -0500 |
commit | a8638030f668884720b8f4456448d0ce33952b05 (patch) | |
tree | 2532b2ef9def879513fad0e304a6a9c98fa798f0 /kernel | |
parent | 316eb661f125397d46f16f94e3c81ad3dc4c1233 (diff) |
cgroup: add cgroup_subsys->post_create()
Currently, there's no way for a controller to find out whether a new
cgroup finished all ->create() allocatinos successfully and is
considered "live" by cgroup.
This becomes a problem later when we add generic descendants walking
to cgroup which can be used by controllers as controllers don't have a
synchronization point where it can synchronize against new cgroups
appearing in such walks.
This patch adds ->post_create(). It's called after all ->create()
succeeded and the cgroup is linked into the generic cgroup hierarchy.
This plays the counterpart of ->pre_destroy().
When used in combination with the to-be-added generic descendant
iterators, ->post_create() can be used to implement reliable state
inheritance. It will be explained with the descendant iterators.
v2: Added a paragraph about its future use w/ descendant iterators per
Michal.
v3: Forgot to add ->post_create() invocation to cgroup_load_subsys().
Fixed.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Michal Hocko <mhocko@suse.cz>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Li Zefan <lizefan@huawei.com>
Cc: Glauber Costa <glommer@parallels.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 998ab5957c6a..26f2edbaf4f5 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4059,10 +4059,15 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4059 | if (err < 0) | 4059 | if (err < 0) |
4060 | goto err_remove; | 4060 | goto err_remove; |
4061 | 4061 | ||
4062 | /* each css holds a ref to the cgroup's dentry */ | 4062 | for_each_subsys(root, ss) { |
4063 | for_each_subsys(root, ss) | 4063 | /* each css holds a ref to the cgroup's dentry */ |
4064 | dget(dentry); | 4064 | dget(dentry); |
4065 | 4065 | ||
4066 | /* creation succeeded, notify subsystems */ | ||
4067 | if (ss->post_create) | ||
4068 | ss->post_create(cgrp); | ||
4069 | } | ||
4070 | |||
4066 | /* The cgroup directory was pre-locked for us */ | 4071 | /* The cgroup directory was pre-locked for us */ |
4067 | BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex)); | 4072 | BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex)); |
4068 | 4073 | ||
@@ -4280,6 +4285,9 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) | |||
4280 | 4285 | ||
4281 | ss->active = 1; | 4286 | ss->active = 1; |
4282 | 4287 | ||
4288 | if (ss->post_create) | ||
4289 | ss->post_create(&ss->root->top_cgroup); | ||
4290 | |||
4283 | /* this function shouldn't be used with modular subsystems, since they | 4291 | /* this function shouldn't be used with modular subsystems, since they |
4284 | * need to register a subsys_id, among other things */ | 4292 | * need to register a subsys_id, among other things */ |
4285 | BUG_ON(ss->module); | 4293 | BUG_ON(ss->module); |
@@ -4389,6 +4397,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss) | |||
4389 | 4397 | ||
4390 | ss->active = 1; | 4398 | ss->active = 1; |
4391 | 4399 | ||
4400 | if (ss->post_create) | ||
4401 | ss->post_create(&ss->root->top_cgroup); | ||
4402 | |||
4392 | /* success! */ | 4403 | /* success! */ |
4393 | mutex_unlock(&cgroup_mutex); | 4404 | mutex_unlock(&cgroup_mutex); |
4394 | return 0; | 4405 | return 0; |