mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
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>
This commit is contained in:
parent
316eb661f1
commit
a8638030f6
@ -438,6 +438,7 @@ int cgroup_taskset_size(struct cgroup_taskset *tset);
|
||||
|
||||
struct cgroup_subsys {
|
||||
struct cgroup_subsys_state *(*create)(struct cgroup *cgrp);
|
||||
void (*post_create)(struct cgroup *cgrp);
|
||||
void (*pre_destroy)(struct cgroup *cgrp);
|
||||
void (*destroy)(struct cgroup *cgrp);
|
||||
int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
|
||||
|
@ -4059,10 +4059,15 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
|
||||
if (err < 0)
|
||||
goto err_remove;
|
||||
|
||||
/* each css holds a ref to the cgroup's dentry */
|
||||
for_each_subsys(root, ss)
|
||||
for_each_subsys(root, ss) {
|
||||
/* each css holds a ref to the cgroup's dentry */
|
||||
dget(dentry);
|
||||
|
||||
/* creation succeeded, notify subsystems */
|
||||
if (ss->post_create)
|
||||
ss->post_create(cgrp);
|
||||
}
|
||||
|
||||
/* The cgroup directory was pre-locked for us */
|
||||
BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex));
|
||||
|
||||
@ -4280,6 +4285,9 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
|
||||
|
||||
ss->active = 1;
|
||||
|
||||
if (ss->post_create)
|
||||
ss->post_create(&ss->root->top_cgroup);
|
||||
|
||||
/* this function shouldn't be used with modular subsystems, since they
|
||||
* need to register a subsys_id, among other things */
|
||||
BUG_ON(ss->module);
|
||||
@ -4389,6 +4397,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
|
||||
|
||||
ss->active = 1;
|
||||
|
||||
if (ss->post_create)
|
||||
ss->post_create(&ss->root->top_cgroup);
|
||||
|
||||
/* success! */
|
||||
mutex_unlock(&cgroup_mutex);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user