aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/sched.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/sched.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/sched.h')
-rw-r--r--include/linux/sched.h5
1 files changed, 4 insertions, 1 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index bc9952991710..fd9436a3a545 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1245,6 +1245,9 @@ struct task_struct {
1245 const struct sched_class *sched_class; 1245 const struct sched_class *sched_class;
1246 struct sched_entity se; 1246 struct sched_entity se;
1247 struct sched_rt_entity rt; 1247 struct sched_rt_entity rt;
1248#ifdef CONFIG_CGROUP_SCHED
1249 struct task_group *sched_task_group;
1250#endif
1248 1251
1249#ifdef CONFIG_PREEMPT_NOTIFIERS 1252#ifdef CONFIG_PREEMPT_NOTIFIERS
1250 /* list of struct preempt_notifier: */ 1253 /* list of struct preempt_notifier: */
@@ -2724,7 +2727,7 @@ extern int sched_group_set_rt_period(struct task_group *tg,
2724extern long sched_group_rt_period(struct task_group *tg); 2727extern long sched_group_rt_period(struct task_group *tg);
2725extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk); 2728extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk);
2726#endif 2729#endif
2727#endif 2730#endif /* CONFIG_CGROUP_SCHED */
2728 2731
2729extern int task_can_switch_user(struct user_struct *up, 2732extern int task_can_switch_user(struct user_struct *up,
2730 struct task_struct *tsk); 2733 struct task_struct *tsk);