summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/cgroup.h26
-rw-r--r--kernel/cgroup.c41
2 files changed, 22 insertions, 45 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 305e94ee17f5..b42251a23129 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -412,12 +412,11 @@ struct cftype {
unsigned int flags;
/*
- * The subsys this file belongs to. Initialized automatically
- * during registration. NULL for cgroup core files.
+ * Fields used for internal bookkeeping. Initialized automatically
+ * during registration.
*/
- struct cgroup_subsys *ss;
-
- /* kernfs_ops to use, initialized automatically during registration */
+ struct cgroup_subsys *ss; /* NULL for cgroup core files */
+ struct list_head node; /* anchored at ss->cfts */
struct kernfs_ops *kf_ops;
/*
@@ -472,16 +471,6 @@ struct cftype {
};
/*
- * cftype_sets describe cftypes belonging to a subsystem and are chained at
- * cgroup_subsys->cftsets. Each cftset points to an array of cftypes
- * terminated by zero length name.
- */
-struct cftype_set {
- struct list_head node; /* chained at subsys->cftsets */
- struct cftype *cfts;
-};
-
-/*
* See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This
* function can be called as long as @cgrp is accessible.
*/
@@ -597,8 +586,11 @@ struct cgroup_subsys {
/* link to parent, protected by cgroup_lock() */
struct cgroupfs_root *root;
- /* list of cftype_sets */
- struct list_head cftsets;
+ /*
+ * List of cftypes. Each entry is the first entry of an array
+ * terminated by zero length name.
+ */
+ struct list_head cfts;
/* base cftypes, automatically registered with subsys itself */
struct cftype *base_cftypes;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index a2cbd1549995..506ebd61d1c2 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1016,12 +1016,12 @@ static void cgroup_clear_dir(struct cgroup *cgrp, unsigned long subsys_mask)
int i;
for_each_subsys(ss, i) {
- struct cftype_set *set;
+ struct cftype *cfts;
if (!test_bit(i, &subsys_mask))
continue;
- list_for_each_entry(set, &ss->cftsets, node)
- cgroup_addrm_files(cgrp, set->cfts, false);
+ list_for_each_entry(cfts, &ss->cfts, node)
+ cgroup_addrm_files(cgrp, cfts, false);
}
}
@@ -2392,6 +2392,8 @@ static int cgroup_init_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
for (cft = cfts; cft->name[0] != '\0'; cft++) {
struct kernfs_ops *kf_ops;
+ WARN_ON(cft->ss || cft->kf_ops);
+
if (cft->seq_start)
kf_ops = &cgroup_kf_ops;
else
@@ -2430,26 +2432,15 @@ static int cgroup_init_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
*/
int cgroup_rm_cftypes(struct cftype *cfts)
{
- struct cftype *found = NULL;
- struct cftype_set *set;
-
if (!cfts || !cfts[0].ss)
return -ENOENT;
cgroup_cfts_prepare();
+ list_del(&cfts->node);
+ cgroup_cfts_commit(cfts, false);
- list_for_each_entry(set, &cfts[0].ss->cftsets, node) {
- if (set->cfts == cfts) {
- list_del(&set->node);
- kfree(set);
- found = cfts;
- break;
- }
- }
-
- cgroup_cfts_commit(found, false);
cgroup_exit_cftypes(cfts);
- return found ? 0 : -ENOENT;
+ return 0;
}
/**
@@ -2468,20 +2459,14 @@ int cgroup_rm_cftypes(struct cftype *cfts)
*/
int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
{
- struct cftype_set *set;
int ret;
- set = kzalloc(sizeof(*set), GFP_KERNEL);
- if (!set)
- return -ENOMEM;
-
ret = cgroup_init_cftypes(ss, cfts);
if (ret)
return ret;
cgroup_cfts_prepare();
- set->cfts = cfts;
- list_add_tail(&set->node, &ss->cftsets);
+ list_add_tail(&cfts->node, &ss->cfts);
ret = cgroup_cfts_commit(cfts, true);
if (ret)
cgroup_rm_cftypes(cfts);
@@ -3574,13 +3559,13 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask)
/* process cftsets of each subsystem */
for_each_subsys(ss, i) {
- struct cftype_set *set;
+ struct cftype *cfts;
if (!test_bit(i, &subsys_mask))
continue;
- list_for_each_entry(set, &ss->cftsets, node) {
- ret = cgroup_addrm_files(cgrp, set->cfts, true);
+ list_for_each_entry(cfts, &ss->cfts, node) {
+ ret = cgroup_addrm_files(cgrp, cfts, true);
if (ret < 0)
goto err;
}
@@ -4169,7 +4154,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
mutex_lock(&cgroup_tree_mutex);
mutex_lock(&cgroup_mutex);
- INIT_LIST_HEAD(&ss->cftsets);
+ INIT_LIST_HEAD(&ss->cfts);
/* Create the top cgroup state for this subsystem */
ss->root = &cgroup_dummy_root;