diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 68 |
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 | */ |
4231 | void cgroup_exit(struct task_struct *tsk, int run_callbacks) | 4229 | void 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 | */ | ||
4822 | struct 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 |
4817 | static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss, | 4843 | static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss, |
4818 | struct cgroup *cont) | 4844 | struct cgroup *cont) |