diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cgroup.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index dae50d0d8e4b..4936d8886b4f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -1850,14 +1850,14 @@ static int cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp, | |||
| 1850 | struct css_set *newcg; | 1850 | struct css_set *newcg; |
| 1851 | 1851 | ||
| 1852 | /* | 1852 | /* |
| 1853 | * get old css_set. we need to take task_lock and refcount it, because | 1853 | * get old css_set. We are synchronized through threadgroup_lock() |
| 1854 | * an exiting task can change its css_set to init_css_set and drop its | 1854 | * against PF_EXITING setting such that we can't race against |
| 1855 | * old one without taking cgroup_mutex. | 1855 | * cgroup_exit() changing the css_set to init_css_set and dropping the |
| 1856 | * old one. | ||
| 1856 | */ | 1857 | */ |
| 1857 | task_lock(tsk); | 1858 | WARN_ON_ONCE(tsk->flags & PF_EXITING); |
| 1858 | oldcg = tsk->cgroups; | 1859 | oldcg = tsk->cgroups; |
| 1859 | get_css_set(oldcg); | 1860 | get_css_set(oldcg); |
| 1860 | task_unlock(tsk); | ||
| 1861 | 1861 | ||
| 1862 | /* locate or allocate a new css_set for this task. */ | 1862 | /* locate or allocate a new css_set for this task. */ |
| 1863 | if (guarantee) { | 1863 | if (guarantee) { |
| @@ -1879,9 +1879,7 @@ static int cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp, | |||
| 1879 | } | 1879 | } |
| 1880 | put_css_set(oldcg); | 1880 | put_css_set(oldcg); |
| 1881 | 1881 | ||
| 1882 | /* @tsk can't exit as its threadgroup is locked */ | ||
| 1883 | task_lock(tsk); | 1882 | task_lock(tsk); |
| 1884 | WARN_ON_ONCE(tsk->flags & PF_EXITING); | ||
| 1885 | rcu_assign_pointer(tsk->cgroups, newcg); | 1883 | rcu_assign_pointer(tsk->cgroups, newcg); |
| 1886 | task_unlock(tsk); | 1884 | task_unlock(tsk); |
| 1887 | 1885 | ||
| @@ -2182,11 +2180,13 @@ int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader) | |||
| 2182 | /* nothing to do if this task is already in the cgroup */ | 2180 | /* nothing to do if this task is already in the cgroup */ |
| 2183 | if (tc->cgrp == cgrp) | 2181 | if (tc->cgrp == cgrp) |
| 2184 | continue; | 2182 | continue; |
| 2185 | /* get old css_set pointer */ | 2183 | /* |
| 2186 | task_lock(tc->task); | 2184 | * get old css_set pointer. threadgroup is locked so this is |
| 2185 | * safe against concurrent cgroup_exit() changing this to | ||
| 2186 | * init_css_set. | ||
| 2187 | */ | ||
| 2187 | oldcg = tc->task->cgroups; | 2188 | oldcg = tc->task->cgroups; |
| 2188 | get_css_set(oldcg); | 2189 | get_css_set(oldcg); |
| 2189 | task_unlock(tc->task); | ||
| 2190 | /* see if the new one for us is already in the list? */ | 2190 | /* see if the new one for us is already in the list? */ |
| 2191 | if (css_set_check_fetched(cgrp, tc->task, oldcg, &newcg_list)) { | 2191 | if (css_set_check_fetched(cgrp, tc->task, oldcg, &newcg_list)) { |
| 2192 | /* was already there, nothing to do. */ | 2192 | /* was already there, nothing to do. */ |
