summaryrefslogtreecommitdiffstats
path: root/kernel/Kconfig.freezer
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2015-10-07 14:14:13 +0200
committerIngo Molnar <mingo@kernel.org>2015-12-04 10:26:43 +0100
commitecf7d01c229d11a44609c0067889372c91fb4f36 (patch)
tree244e7e8752a7fa9a9dc8cb36cd6ce4ef04042c95 /kernel/Kconfig.freezer
parentsched/core: Better document the try_to_wake_up() barriers (diff)
downloadlinux-ecf7d01c229d11a44609c0067889372c91fb4f36.tar.xz
linux-ecf7d01c229d11a44609c0067889372c91fb4f36.zip
sched/core: Fix an SMP ordering race in try_to_wake_up() vs. schedule()
Oleg noticed that its possible to falsely observe p->on_cpu == 0 such that we'll prematurely continue with the wakeup and effectively run p on two CPUs at the same time. Even though the overlap is very limited; the task is in the middle of being scheduled out; it could still result in corruption of the scheduler data structures. CPU0 CPU1 set_current_state(...) <preempt_schedule> context_switch(X, Y) prepare_lock_switch(Y) Y->on_cpu = 1; finish_lock_switch(X) store_release(X->on_cpu, 0); try_to_wake_up(X) LOCK(p->pi_lock); t = X->on_cpu; // 0 context_switch(Y, X) prepare_lock_switch(X) X->on_cpu = 1; finish_lock_switch(Y) store_release(Y->on_cpu, 0); </preempt_schedule> schedule(); deactivate_task(X); X->on_rq = 0; if (X->on_rq) // false if (t) while (X->on_cpu) cpu_relax(); context_switch(X, ..) finish_lock_switch(X) store_release(X->on_cpu, 0); Avoid the load of X->on_cpu being hoisted over the X->on_rq load. Reported-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/Kconfig.freezer')
0 files changed, 0 insertions, 0 deletions