diff options
Diffstat (limited to 'kernel/cgroup.c')
| -rw-r--r-- | kernel/cgroup.c | 41 | 
1 files changed, 10 insertions, 31 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 13774b3b39a..f24f724620d 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1962,9 +1962,8 @@ static void cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,  	 * trading it for newcg is protected by cgroup_mutex, we're safe to drop  	 * it here; it will be freed under RCU.  	 */ -	put_css_set(oldcg); -  	set_bit(CGRP_RELEASABLE, &oldcgrp->flags); +	put_css_set(oldcg);  }  /** @@ -4815,31 +4814,20 @@ static const struct file_operations proc_cgroupstats_operations = {   *   * A pointer to the shared css_set was automatically copied in   * fork.c by dup_task_struct().  However, we ignore that copy, since - * it was not made under the protection of RCU, cgroup_mutex or - * threadgroup_change_begin(), so it might no longer be a valid - * cgroup pointer.  cgroup_attach_task() might have already changed - * current->cgroups, allowing the previously referenced cgroup - * group to be removed and freed. - * - * Outside the pointer validity we also need to process the css_set - * inheritance between threadgoup_change_begin() and - * threadgoup_change_end(), this way there is no leak in any process - * wide migration performed by cgroup_attach_proc() that could otherwise - * miss a thread because it is too early or too late in the fork stage. + * it was not made under the protection of RCU or cgroup_mutex, so + * might no longer be a valid cgroup pointer.  cgroup_attach_task() might + * have already changed current->cgroups, allowing the previously + * referenced cgroup group to be removed and freed.   *   * At the point that cgroup_fork() is called, 'current' is the parent   * task, and the passed argument 'child' points to the child task.   */  void cgroup_fork(struct task_struct *child)  { -	/* -	 * We don't need to task_lock() current because current->cgroups -	 * can't be changed concurrently here. The parent obviously hasn't -	 * exited and called cgroup_exit(), and we are synchronized against -	 * cgroup migration through threadgroup_change_begin(). -	 */ +	task_lock(current);  	child->cgroups = current->cgroups;  	get_css_set(child->cgroups); +	task_unlock(current);  	INIT_LIST_HEAD(&child->cg_list);  } @@ -4895,19 +4883,10 @@ void cgroup_post_fork(struct task_struct *child)  	 */  	if (use_task_css_set_links) {  		write_lock(&css_set_lock); -		if (list_empty(&child->cg_list)) { -			/* -			 * It's safe to use child->cgroups without task_lock() -			 * here because we are protected through -			 * threadgroup_change_begin() against concurrent -			 * css_set change in cgroup_task_migrate(). Also -			 * the task can't exit at that point until -			 * wake_up_new_task() is called, so we are protected -			 * against cgroup_exit() setting child->cgroup to -			 * init_css_set. -			 */ +		task_lock(child); +		if (list_empty(&child->cg_list))  			list_add(&child->cg_list, &child->cgroups->tasks); -		} +		task_unlock(child);  		write_unlock(&css_set_lock);  	}  }  |