/* list of cftype_sets */
struct list_head cftsets;
- /* base cftypes, automatically [de]registered with subsys itself */
+ /* base cftypes, automatically registered with subsys itself */
struct cftype *base_cftypes;
- struct cftype_set base_cftset;
};
#define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
return ret;
}
-static void __init cgroup_init_cftsets(struct cgroup_subsys *ss)
-{
- INIT_LIST_HEAD(&ss->cftsets);
-
- /*
- * base_cftset is embedded in subsys itself, no need to worry about
- * deregistration.
- */
- if (ss->base_cftypes) {
- struct cftype *cft;
-
- for (cft = ss->base_cftypes; cft->name[0] != '\0'; cft++)
- cft->ss = ss;
-
- ss->base_cftset.cfts = ss->base_cftypes;
- list_add_tail(&ss->base_cftset.node, &ss->cftsets);
- }
-}
-
static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
{
struct cgroup_subsys_state *css;
mutex_lock(&cgroup_tree_mutex);
mutex_lock(&cgroup_mutex);
- /* init base cftset */
- cgroup_init_cftsets(ss);
+ INIT_LIST_HEAD(&ss->cftsets);
/* Create the top cgroup state for this subsystem */
ss->root = &cgroup_dummy_root;
for_each_subsys(ss, i) {
if (!ss->early_init)
cgroup_init_subsys(ss);
+
+ /*
+ * cftype registration needs kmalloc and can't be done
+ * during early_init. Register base cftypes separately.
+ */
+ if (ss->base_cftypes)
+ WARN_ON(cgroup_add_cftypes(ss, ss->base_cftypes));
}
/* allocate id for the dummy hierarchy */