aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/init_task.h
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2012-06-22 07:36:05 -0400
committerIngo Molnar <mingo@kernel.org>2012-07-24 07:58:20 -0400
commit8323f26ce3425460769605a6aece7a174edaa7d1 (patch)
tree44daa0dafa49cedc9301efd1417c6c2ac338c1c7 /include/linux/init_task.h
parent88b8dac0a14c511ff41486b83a8c3d688936eec0 (diff)
sched: Fix race in task_group()
Stefan reported a crash on a kernel before a3e5d1091c1 ("sched: Don't call task_group() too many times in set_task_rq()"), he found the reason to be that the multiple task_group() invocations in set_task_rq() returned different values. Looking at all that I found a lack of serialization and plain wrong comments. The below tries to fix it using an extra pointer which is updated under the appropriate scheduler locks. Its not pretty, but I can't really see another way given how all the cgroup stuff works. Reported-and-tested-by: Stefan Bader <stefan.bader@canonical.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1340364965.18025.71.camel@twins Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/init_task.h')
-rw-r--r--include/linux/init_task.h12
1 files changed, 11 insertions, 1 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 9e65eff6af3b..b806b821e735 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -123,8 +123,17 @@ extern struct group_info init_groups;
123 123
124extern struct cred init_cred; 124extern struct cred init_cred;
125 125
126extern struct task_group root_task_group;
127
128#ifdef CONFIG_CGROUP_SCHED
129# define INIT_CGROUP_SCHED(tsk) \
130 .sched_task_group = &root_task_group,
131#else
132# define INIT_CGROUP_SCHED(tsk)
133#endif
134
126#ifdef CONFIG_PERF_EVENTS 135#ifdef CONFIG_PERF_EVENTS
127# define INIT_PERF_EVENTS(tsk) \ 136# define INIT_PERF_EVENTS(tsk) \
128 .perf_event_mutex = \ 137 .perf_event_mutex = \
129 __MUTEX_INITIALIZER(tsk.perf_event_mutex), \ 138 __MUTEX_INITIALIZER(tsk.perf_event_mutex), \
130 .perf_event_list = LIST_HEAD_INIT(tsk.perf_event_list), 139 .perf_event_list = LIST_HEAD_INIT(tsk.perf_event_list),
@@ -161,6 +170,7 @@ extern struct cred init_cred;
161 }, \ 170 }, \
162 .tasks = LIST_HEAD_INIT(tsk.tasks), \ 171 .tasks = LIST_HEAD_INIT(tsk.tasks), \
163 INIT_PUSHABLE_TASKS(tsk) \ 172 INIT_PUSHABLE_TASKS(tsk) \
173 INIT_CGROUP_SCHED(tsk) \
164 .ptraced = LIST_HEAD_INIT(tsk.ptraced), \ 174 .ptraced = LIST_HEAD_INIT(tsk.ptraced), \
165 .ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \ 175 .ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \
166 .real_parent = &tsk, \ 176 .real_parent = &tsk, \