diff options
| author | Peter Zijlstra <peterz@infradead.org> | 2012-06-22 13:36:05 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2012-07-24 13:58:20 +0200 | 
| commit | 8323f26ce3425460769605a6aece7a174edaa7d1 (patch) | |
| tree | 44daa0dafa49cedc9301efd1417c6c2ac338c1c7 /include/linux/init_task.h | |
| parent | 88b8dac0a14c511ff41486b83a8c3d688936eec0 (diff) | |
| download | olio-linux-3.10-8323f26ce3425460769605a6aece7a174edaa7d1.tar.xz olio-linux-3.10-8323f26ce3425460769605a6aece7a174edaa7d1.zip  | |
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.h | 12 | 
1 files changed, 11 insertions, 1 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 9e65eff6af3..b806b821e73 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -123,8 +123,17 @@ extern struct group_info init_groups;  extern struct cred init_cred; +extern struct task_group root_task_group; + +#ifdef CONFIG_CGROUP_SCHED +# define INIT_CGROUP_SCHED(tsk)						\ +	.sched_task_group = &root_task_group, +#else +# define INIT_CGROUP_SCHED(tsk) +#endif +  #ifdef CONFIG_PERF_EVENTS -# define INIT_PERF_EVENTS(tsk)					\ +# define INIT_PERF_EVENTS(tsk)						\  	.perf_event_mutex = 						\  		 __MUTEX_INITIALIZER(tsk.perf_event_mutex),		\  	.perf_event_list = LIST_HEAD_INIT(tsk.perf_event_list), @@ -161,6 +170,7 @@ extern struct cred init_cred;  	},								\  	.tasks		= LIST_HEAD_INIT(tsk.tasks),			\  	INIT_PUSHABLE_TASKS(tsk)					\ +	INIT_CGROUP_SCHED(tsk)						\  	.ptraced	= LIST_HEAD_INIT(tsk.ptraced),			\  	.ptrace_entry	= LIST_HEAD_INIT(tsk.ptrace_entry),		\  	.real_parent	= &tsk,						\  |