diff options
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index c6bd67b3fcf6..548d8d4e86d0 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4595,10 +4595,19 @@ void cgroup_post_fork(struct task_struct *child) | |||
4595 | { | 4595 | { |
4596 | if (use_task_css_set_links) { | 4596 | if (use_task_css_set_links) { |
4597 | write_lock(&css_set_lock); | 4597 | write_lock(&css_set_lock); |
4598 | task_lock(child); | 4598 | if (list_empty(&child->cg_list)) { |
4599 | if (list_empty(&child->cg_list)) | 4599 | /* |
4600 | * It's safe to use child->cgroups without task_lock() | ||
4601 | * here because we are protected through | ||
4602 | * threadgroup_change_begin() against concurrent | ||
4603 | * css_set change in cgroup_task_migrate(). Also | ||
4604 | * the task can't exit at that point until | ||
4605 | * wake_up_new_task() is called, so we are protected | ||
4606 | * against cgroup_exit() setting child->cgroup to | ||
4607 | * init_css_set. | ||
4608 | */ | ||
4600 | list_add(&child->cg_list, &child->cgroups->tasks); | 4609 | list_add(&child->cg_list, &child->cgroups->tasks); |
4601 | task_unlock(child); | 4610 | } |
4602 | write_unlock(&css_set_lock); | 4611 | write_unlock(&css_set_lock); |
4603 | } | 4612 | } |
4604 | } | 4613 | } |