cgroup: simplify cgroup_load_subsys() failure path
Now that cgroup_unload_subsys() can tell whether the root css is online or not, we can safely call cgroup_unload_subsys() after idr init failure in cgroup_load_subsys(). Replace the manual unrolling and invoke cgroup_unload_subsys() on failure. This drops cgroup_mutex inbetween but should be safe as the subsystem will fail try_module_get() and thus can't be mounted inbetween. As this means that cgroup_unload_subsys() can be called before css_sets are rehashed, remove BUG_ON() on %NULL css_set->subsys[] from cgroup_unload_subsys(). Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
This commit is contained in:
parent
a31f2d3ff7
commit
d19e19de48
|
@ -4400,8 +4400,8 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
|
|||
*/
|
||||
int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
|
||||
{
|
||||
int i;
|
||||
struct cgroup_subsys_state *css;
|
||||
int i, ret;
|
||||
|
||||
/* check name and function validity */
|
||||
if (ss->name == NULL || strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN ||
|
||||
|
@ -4452,15 +4452,9 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
|
|||
init_cgroup_css(css, ss, dummytop);
|
||||
/* init_idr must be after init_cgroup_css because it sets css->id. */
|
||||
if (ss->use_id) {
|
||||
int ret = cgroup_init_idr(ss, css);
|
||||
if (ret) {
|
||||
ss->destroy(dummytop);
|
||||
dummytop->subsys[ss->subsys_id] = NULL;
|
||||
subsys[ss->subsys_id] = NULL;
|
||||
list_del_init(&ss->sibling);
|
||||
mutex_unlock(&cgroup_mutex);
|
||||
return ret;
|
||||
}
|
||||
ret = cgroup_init_idr(ss, css);
|
||||
if (ret)
|
||||
goto err_unload;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4498,6 +4492,12 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
|
|||
/* success! */
|
||||
mutex_unlock(&cgroup_mutex);
|
||||
return 0;
|
||||
|
||||
err_unload:
|
||||
mutex_unlock(&cgroup_mutex);
|
||||
/* @ss can't be mounted here as try_module_get() would fail */
|
||||
cgroup_unload_subsys(ss);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cgroup_load_subsys);
|
||||
|
||||
|
@ -4548,7 +4548,6 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
|
|||
struct css_set *cg = link->cg;
|
||||
|
||||
hlist_del(&cg->hlist);
|
||||
BUG_ON(!cg->subsys[ss->subsys_id]);
|
||||
cg->subsys[ss->subsys_id] = NULL;
|
||||
hhead = css_set_hash(cg->subsys);
|
||||
hlist_add_head(&cg->hlist, hhead);
|
||||
|
|
Loading…
Reference in a new issue