diff options
author | Tejun Heo <tj@kernel.org> | 2012-11-19 12:02:12 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-11-19 12:02:12 -0500 |
commit | 0a950f65e1e64f4e82b4b5507773848ea88bcb8e (patch) | |
tree | 90106ea13abc3cfe9226dc0c7628ccad136f92b4 /kernel/cgroup.c | |
parent | 033fa1c5f5f73833598a0beb022c0048fb769dad (diff) |
cgroup: add cgroup->id
With the introduction of generic cgroup hierarchy iterators, css_id is
being phased out. It was unnecessarily complex, id'ing the wrong
thing (cgroups need IDs, not CSSes) and has other oddities like not
being available at ->css_alloc().
This patch adds cgroup->id, which is a simple per-hierarchy
ida-allocated ID which is assigned before ->css_alloc() and released
after ->css_free().
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 96719f73e95d..6db01417d39a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -138,6 +138,9 @@ struct cgroupfs_root { | |||
138 | /* Hierarchy-specific flags */ | 138 | /* Hierarchy-specific flags */ |
139 | unsigned long flags; | 139 | unsigned long flags; |
140 | 140 | ||
141 | /* IDs for cgroups in this hierarchy */ | ||
142 | struct ida cgroup_ida; | ||
143 | |||
141 | /* The path to use for release notifications. */ | 144 | /* The path to use for release notifications. */ |
142 | char release_agent_path[PATH_MAX]; | 145 | char release_agent_path[PATH_MAX]; |
143 | 146 | ||
@@ -890,6 +893,7 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
890 | 893 | ||
891 | simple_xattrs_free(&cgrp->xattrs); | 894 | simple_xattrs_free(&cgrp->xattrs); |
892 | 895 | ||
896 | ida_simple_remove(&cgrp->root->cgroup_ida, cgrp->id); | ||
893 | kfree_rcu(cgrp, rcu_head); | 897 | kfree_rcu(cgrp, rcu_head); |
894 | } else { | 898 | } else { |
895 | struct cfent *cfe = __d_cfe(dentry); | 899 | struct cfent *cfe = __d_cfe(dentry); |
@@ -1465,6 +1469,7 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts) | |||
1465 | 1469 | ||
1466 | root->subsys_mask = opts->subsys_mask; | 1470 | root->subsys_mask = opts->subsys_mask; |
1467 | root->flags = opts->flags; | 1471 | root->flags = opts->flags; |
1472 | ida_init(&root->cgroup_ida); | ||
1468 | if (opts->release_agent) | 1473 | if (opts->release_agent) |
1469 | strcpy(root->release_agent_path, opts->release_agent); | 1474 | strcpy(root->release_agent_path, opts->release_agent); |
1470 | if (opts->name) | 1475 | if (opts->name) |
@@ -1483,6 +1488,7 @@ static void cgroup_drop_root(struct cgroupfs_root *root) | |||
1483 | spin_lock(&hierarchy_id_lock); | 1488 | spin_lock(&hierarchy_id_lock); |
1484 | ida_remove(&hierarchy_ida, root->hierarchy_id); | 1489 | ida_remove(&hierarchy_ida, root->hierarchy_id); |
1485 | spin_unlock(&hierarchy_id_lock); | 1490 | spin_unlock(&hierarchy_id_lock); |
1491 | ida_destroy(&root->cgroup_ida); | ||
1486 | kfree(root); | 1492 | kfree(root); |
1487 | } | 1493 | } |
1488 | 1494 | ||
@@ -4093,10 +4099,15 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4093 | struct cgroup_subsys *ss; | 4099 | struct cgroup_subsys *ss; |
4094 | struct super_block *sb = root->sb; | 4100 | struct super_block *sb = root->sb; |
4095 | 4101 | ||
4102 | /* allocate the cgroup and its ID, 0 is reserved for the root */ | ||
4096 | cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); | 4103 | cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); |
4097 | if (!cgrp) | 4104 | if (!cgrp) |
4098 | return -ENOMEM; | 4105 | return -ENOMEM; |
4099 | 4106 | ||
4107 | cgrp->id = ida_simple_get(&root->cgroup_ida, 1, 0, GFP_KERNEL); | ||
4108 | if (cgrp->id < 0) | ||
4109 | goto err_free_cgrp; | ||
4110 | |||
4100 | /* | 4111 | /* |
4101 | * Only live parents can have children. Note that the liveliness | 4112 | * Only live parents can have children. Note that the liveliness |
4102 | * check isn't strictly necessary because cgroup_mkdir() and | 4113 | * check isn't strictly necessary because cgroup_mkdir() and |
@@ -4106,7 +4117,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4106 | */ | 4117 | */ |
4107 | if (!cgroup_lock_live_group(parent)) { | 4118 | if (!cgroup_lock_live_group(parent)) { |
4108 | err = -ENODEV; | 4119 | err = -ENODEV; |
4109 | goto err_free_cgrp; | 4120 | goto err_free_id; |
4110 | } | 4121 | } |
4111 | 4122 | ||
4112 | /* Grab a reference on the superblock so the hierarchy doesn't | 4123 | /* Grab a reference on the superblock so the hierarchy doesn't |
@@ -4198,6 +4209,8 @@ err_free_all: | |||
4198 | mutex_unlock(&cgroup_mutex); | 4209 | mutex_unlock(&cgroup_mutex); |
4199 | /* Release the reference count that we took on the superblock */ | 4210 | /* Release the reference count that we took on the superblock */ |
4200 | deactivate_super(sb); | 4211 | deactivate_super(sb); |
4212 | err_free_id: | ||
4213 | ida_simple_remove(&root->cgroup_ida, cgrp->id); | ||
4201 | err_free_cgrp: | 4214 | err_free_cgrp: |
4202 | kfree(cgrp); | 4215 | kfree(cgrp); |
4203 | return err; | 4216 | return err; |