aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-06 15:26:23 -0500
committerTejun Heo <tj@kernel.org>2012-11-06 15:26:23 -0500
commit5b805f2a7675634fbdf9ac1c9b2256905ab2ea68 (patch)
treeee00d1e3d757458d66209b926d274491c6c3f61c /kernel/cgroup.c
parent1db1e31b1ee3ae126ef98f39083b5f213c7b41bf (diff)
parent201e72acb2d3821e2de9ce6091e98859c316b29a (diff)
Merge branch 'cgroup/for-3.7-fixes' into cgroup/for-3.8
This is to receive device_cgroup fixes so that further device_cgroup changes can be made in cgroup/for-3.8. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c41
1 files changed, 10 insertions, 31 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index e3045ad4267a..3070164e2036 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1911,9 +1911,8 @@ static void cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,
1911 * trading it for newcg is protected by cgroup_mutex, we're safe to drop 1911 * trading it for newcg is protected by cgroup_mutex, we're safe to drop
1912 * it here; it will be freed under RCU. 1912 * it here; it will be freed under RCU.
1913 */ 1913 */
1914 put_css_set(oldcg);
1915
1916 set_bit(CGRP_RELEASABLE, &oldcgrp->flags); 1914 set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
1915 put_css_set(oldcg);
1917} 1916}
1918 1917
1919/** 1918/**
@@ -4681,31 +4680,20 @@ static const struct file_operations proc_cgroupstats_operations = {
4681 * 4680 *
4682 * A pointer to the shared css_set was automatically copied in 4681 * A pointer to the shared css_set was automatically copied in
4683 * fork.c by dup_task_struct(). However, we ignore that copy, since 4682 * fork.c by dup_task_struct(). However, we ignore that copy, since
4684 * it was not made under the protection of RCU, cgroup_mutex or 4683 * it was not made under the protection of RCU or cgroup_mutex, so
4685 * threadgroup_change_begin(), so it might no longer be a valid 4684 * might no longer be a valid cgroup pointer. cgroup_attach_task() might
4686 * cgroup pointer. cgroup_attach_task() might have already changed 4685 * have already changed current->cgroups, allowing the previously
4687 * current->cgroups, allowing the previously referenced cgroup 4686 * referenced cgroup group to be removed and freed.
4688 * group to be removed and freed.
4689 *
4690 * Outside the pointer validity we also need to process the css_set
4691 * inheritance between threadgoup_change_begin() and
4692 * threadgoup_change_end(), this way there is no leak in any process
4693 * wide migration performed by cgroup_attach_proc() that could otherwise
4694 * miss a thread because it is too early or too late in the fork stage.
4695 * 4687 *
4696 * At the point that cgroup_fork() is called, 'current' is the parent 4688 * At the point that cgroup_fork() is called, 'current' is the parent
4697 * task, and the passed argument 'child' points to the child task. 4689 * task, and the passed argument 'child' points to the child task.
4698 */ 4690 */
4699void cgroup_fork(struct task_struct *child) 4691void cgroup_fork(struct task_struct *child)
4700{ 4692{
4701 /* 4693 task_lock(current);
4702 * We don't need to task_lock() current because current->cgroups
4703 * can't be changed concurrently here. The parent obviously hasn't
4704 * exited and called cgroup_exit(), and we are synchronized against
4705 * cgroup migration through threadgroup_change_begin().
4706 */
4707 child->cgroups = current->cgroups; 4694 child->cgroups = current->cgroups;
4708 get_css_set(child->cgroups); 4695 get_css_set(child->cgroups);
4696 task_unlock(current);
4709 INIT_LIST_HEAD(&child->cg_list); 4697 INIT_LIST_HEAD(&child->cg_list);
4710} 4698}
4711 4699
@@ -4736,19 +4724,10 @@ void cgroup_post_fork(struct task_struct *child)
4736 */ 4724 */
4737 if (use_task_css_set_links) { 4725 if (use_task_css_set_links) {
4738 write_lock(&css_set_lock); 4726 write_lock(&css_set_lock);
4739 if (list_empty(&child->cg_list)) { 4727 task_lock(child);
4740 /* 4728 if (list_empty(&child->cg_list))
4741 * It's safe to use child->cgroups without task_lock()
4742 * here because we are protected through
4743 * threadgroup_change_begin() against concurrent
4744 * css_set change in cgroup_task_migrate(). Also
4745 * the task can't exit at that point until
4746 * wake_up_new_task() is called, so we are protected
4747 * against cgroup_exit() setting child->cgroup to
4748 * init_css_set.
4749 */
4750 list_add(&child->cg_list, &child->cgroups->tasks); 4729 list_add(&child->cg_list, &child->cgroups->tasks);
4751 } 4730 task_unlock(child);
4752 write_unlock(&css_set_lock); 4731 write_unlock(&css_set_lock);
4753 } 4732 }
4754 4733