aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index b24d7027b83c..e31b220a743d 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1813,10 +1813,8 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
1813 1813
1814 /* Update the css_set linked lists if we're using them */ 1814 /* Update the css_set linked lists if we're using them */
1815 write_lock(&css_set_lock); 1815 write_lock(&css_set_lock);
1816 if (!list_empty(&tsk->cg_list)) { 1816 if (!list_empty(&tsk->cg_list))
1817 list_del(&tsk->cg_list); 1817 list_move(&tsk->cg_list, &newcg->tasks);
1818 list_add(&tsk->cg_list, &newcg->tasks);
1819 }
1820 write_unlock(&css_set_lock); 1818 write_unlock(&css_set_lock);
1821 1819
1822 for_each_subsys(root, ss) { 1820 for_each_subsys(root, ss) {
@@ -3655,12 +3653,12 @@ again:
3655 spin_lock(&release_list_lock); 3653 spin_lock(&release_list_lock);
3656 set_bit(CGRP_REMOVED, &cgrp->flags); 3654 set_bit(CGRP_REMOVED, &cgrp->flags);
3657 if (!list_empty(&cgrp->release_list)) 3655 if (!list_empty(&cgrp->release_list))
3658 list_del(&cgrp->release_list); 3656 list_del_init(&cgrp->release_list);
3659 spin_unlock(&release_list_lock); 3657 spin_unlock(&release_list_lock);
3660 3658
3661 cgroup_lock_hierarchy(cgrp->root); 3659 cgroup_lock_hierarchy(cgrp->root);
3662 /* delete this cgroup from parent->children */ 3660 /* delete this cgroup from parent->children */
3663 list_del(&cgrp->sibling); 3661 list_del_init(&cgrp->sibling);
3664 cgroup_unlock_hierarchy(cgrp->root); 3662 cgroup_unlock_hierarchy(cgrp->root);
3665 3663
3666 d = dget(cgrp->dentry); 3664 d = dget(cgrp->dentry);
@@ -3879,7 +3877,7 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
3879 subsys[ss->subsys_id] = NULL; 3877 subsys[ss->subsys_id] = NULL;
3880 3878
3881 /* remove subsystem from rootnode's list of subsystems */ 3879 /* remove subsystem from rootnode's list of subsystems */
3882 list_del(&ss->sibling); 3880 list_del_init(&ss->sibling);
3883 3881
3884 /* 3882 /*
3885 * disentangle the css from all css_sets attached to the dummytop. as 3883 * disentangle the css from all css_sets attached to the dummytop. as
@@ -4230,20 +4228,8 @@ void cgroup_post_fork(struct task_struct *child)
4230 */ 4228 */
4231void cgroup_exit(struct task_struct *tsk, int run_callbacks) 4229void cgroup_exit(struct task_struct *tsk, int run_callbacks)
4232{ 4230{
4233 int i;
4234 struct css_set *cg; 4231 struct css_set *cg;
4235 4232 int i;
4236 if (run_callbacks && need_forkexit_callback) {
4237 /*
4238 * modular subsystems can't use callbacks, so no need to lock
4239 * the subsys array
4240 */
4241 for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
4242 struct cgroup_subsys *ss = subsys[i];
4243 if (ss->exit)
4244 ss->exit(ss, tsk);
4245 }
4246 }
4247 4233
4248 /* 4234 /*
4249 * Unlink from the css_set task list if necessary. 4235 * Unlink from the css_set task list if necessary.
@@ -4253,7 +4239,7 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
4253 if (!list_empty(&tsk->cg_list)) { 4239 if (!list_empty(&tsk->cg_list)) {
4254 write_lock(&css_set_lock); 4240 write_lock(&css_set_lock);
4255 if (!list_empty(&tsk->cg_list)) 4241 if (!list_empty(&tsk->cg_list))
4256 list_del(&tsk->cg_list); 4242 list_del_init(&tsk->cg_list);
4257 write_unlock(&css_set_lock); 4243 write_unlock(&css_set_lock);
4258 } 4244 }
4259 4245
@@ -4261,7 +4247,24 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
4261 task_lock(tsk); 4247 task_lock(tsk);
4262 cg = tsk->cgroups; 4248 cg = tsk->cgroups;
4263 tsk->cgroups = &init_css_set; 4249 tsk->cgroups = &init_css_set;
4250
4251 if (run_callbacks && need_forkexit_callback) {
4252 /*
4253 * modular subsystems can't use callbacks, so no need to lock
4254 * the subsys array
4255 */
4256 for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
4257 struct cgroup_subsys *ss = subsys[i];
4258 if (ss->exit) {
4259 struct cgroup *old_cgrp =
4260 rcu_dereference_raw(cg->subsys[i])->cgroup;
4261 struct cgroup *cgrp = task_cgroup(tsk, i);
4262 ss->exit(ss, cgrp, old_cgrp, tsk);
4263 }
4264 }
4265 }
4264 task_unlock(tsk); 4266 task_unlock(tsk);
4267
4265 if (cg) 4268 if (cg)
4266 put_css_set_taskexit(cg); 4269 put_css_set_taskexit(cg);
4267} 4270}
@@ -4813,6 +4816,29 @@ css_get_next(struct cgroup_subsys *ss, int id,
4813 return ret; 4816 return ret;
4814} 4817}
4815 4818
4819/*
4820 * get corresponding css from file open on cgroupfs directory
4821 */
4822struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
4823{
4824 struct cgroup *cgrp;
4825 struct inode *inode;
4826 struct cgroup_subsys_state *css;
4827
4828 inode = f->f_dentry->d_inode;
4829 /* check in cgroup filesystem dir */
4830 if (inode->i_op != &cgroup_dir_inode_operations)
4831 return ERR_PTR(-EBADF);
4832
4833 if (id < 0 || id >= CGROUP_SUBSYS_COUNT)
4834 return ERR_PTR(-EINVAL);
4835
4836 /* get cgroup */
4837 cgrp = __d_cgrp(f->f_dentry);
4838 css = cgrp->subsys[id];
4839 return css ? css : ERR_PTR(-ENOENT);
4840}
4841
4816#ifdef CONFIG_CGROUP_DEBUG 4842#ifdef CONFIG_CGROUP_DEBUG
4817static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss, 4843static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss,
4818 struct cgroup *cont) 4844 struct cgroup *cont)