This patch adds support for subsys.use_id in module-loadable subsystems. From: Ben Blum Signed-off-by: Ben Blum --- kernel/cgroup.c | 23 +++++++++++++++++------ 1 files changed, 17 insertions(+), 6 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index cc2e1f6..5af59eb 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -240,7 +240,8 @@ struct cg_cgroup_link { static struct css_set init_css_set; static struct cg_cgroup_link init_css_set_link; -static int cgroup_subsys_init_idr(struct cgroup_subsys *ss); +static int cgroup_init_idr(struct cgroup_subsys *ss, + struct cgroup_subsys_state *css); /* css_set_lock protects the list of css_set objects, and the * chain of tasks off each css_set. Nests outside task->alloc_lock @@ -3390,6 +3391,16 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss) mutex_unlock(&cgroup_mutex); return PTR_ERR(css); } + /* call init_idr here because it has a failure case */ + if (ss->use_id) { + int ret = cgroup_init_idr(ss, css); + if (ret) { + ss->destroy(ss, dummytop); + subsys[i] = NULL; + mutex_unlock(&cgroup_mutex); + return ret; + } + } list_add(&ss->sibling, &rootnode.subsys_list); ss->root = &rootnode; @@ -3484,7 +3495,8 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss) /* * remove subsystem's css from the dummytop and free it - need to free * before marking as null because ss->destroy needs the cgrp->subsys - * pointer to find their state. + * pointer to find their state. note that this also takes care of + * freeing the css_id. */ ss->destroy(ss, dummytop); dummytop->subsys[ss->subsys_id] = NULL; @@ -3563,7 +3575,7 @@ int __init cgroup_init(void) if (!ss->early_init) cgroup_init_subsys(ss); if (ss->use_id) - cgroup_subsys_init_idr(ss); + cgroup_init_idr(ss, init_css_set.subsys[ss->subsys_id]); } /* Add init_css_set to the hash table */ @@ -4231,15 +4243,14 @@ err_out: } -static int __init cgroup_subsys_init_idr(struct cgroup_subsys *ss) +static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss, + struct cgroup_subsys_state *rootcss) { struct css_id *newid; - struct cgroup_subsys_state *rootcss; spin_lock_init(&ss->id_lock); idr_init(&ss->idr); - rootcss = init_css_set.subsys[ss->subsys_id]; newid = get_new_cssid(ss, 0); if (IS_ERR(newid)) return PTR_ERR(newid);