diff options
author | Kirill Tkhai <ktkhai@parallels.com> | 2014-10-27 06:18:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-10-28 05:45:59 -0400 |
commit | eeb61e53ea19be0c4015b00b2e8b3b2185436f2b (patch) | |
tree | 87ed33506d580130ac59cc231a6e112c4042b96d | |
parent | cac7f2429872d3733dc3f9915857b1691da2eb2f (diff) |
sched: Fix race between task_group and sched_task_group
The race may happen when somebody is changing task_group of a forking task.
Child's cgroup is the same as parent's after dup_task_struct() (there just
memory copying). Also, cfs_rq and rt_rq are the same as parent's.
But if parent changes its task_group before it's called cgroup_post_fork(),
we do not reflect this situation on child. Child's cfs_rq and rt_rq remain
the same, while child's task_group changes in cgroup_post_fork().
To fix this we introduce fork() method, which calls sched_move_task() directly.
This function changes sched_task_group on appropriate (also its logic has
no problem with freshly created tasks, so we shouldn't introduce something
special; we are able just to use it).
Possibly, this decides the Burke Libbey's problem: https://lkml.org/lkml/2014/10/24/456
Signed-off-by: Kirill Tkhai <ktkhai@parallels.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/1414405105.19914.169.camel@tkhai
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | kernel/sched/core.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 44999505e1bf..dde8adb7d0c0 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -7833,6 +7833,11 @@ static void cpu_cgroup_css_offline(struct cgroup_subsys_state *css) | |||
7833 | sched_offline_group(tg); | 7833 | sched_offline_group(tg); |
7834 | } | 7834 | } |
7835 | 7835 | ||
7836 | static void cpu_cgroup_fork(struct task_struct *task) | ||
7837 | { | ||
7838 | sched_move_task(task); | ||
7839 | } | ||
7840 | |||
7836 | static int cpu_cgroup_can_attach(struct cgroup_subsys_state *css, | 7841 | static int cpu_cgroup_can_attach(struct cgroup_subsys_state *css, |
7837 | struct cgroup_taskset *tset) | 7842 | struct cgroup_taskset *tset) |
7838 | { | 7843 | { |
@@ -8205,6 +8210,7 @@ struct cgroup_subsys cpu_cgrp_subsys = { | |||
8205 | .css_free = cpu_cgroup_css_free, | 8210 | .css_free = cpu_cgroup_css_free, |
8206 | .css_online = cpu_cgroup_css_online, | 8211 | .css_online = cpu_cgroup_css_online, |
8207 | .css_offline = cpu_cgroup_css_offline, | 8212 | .css_offline = cpu_cgroup_css_offline, |
8213 | .fork = cpu_cgroup_fork, | ||
8208 | .can_attach = cpu_cgroup_can_attach, | 8214 | .can_attach = cpu_cgroup_can_attach, |
8209 | .attach = cpu_cgroup_attach, | 8215 | .attach = cpu_cgroup_attach, |
8210 | .exit = cpu_cgroup_exit, | 8216 | .exit = cpu_cgroup_exit, |