Commit e14c8bf8 authored by Rusty Russell's avatar Rusty Russell Committed by Linus Torvalds

stop_machine: fix race with return value (fixes Bug #11989)

Bug #11989: Suspend failure on NForce4-based boards due to chanes in
stop_machine

We should not access active.fnret outside the lock; in theory the next
stop_machine could overwrite it.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Tested-by: default avatar"Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5c06fe77
...@@ -112,7 +112,7 @@ static int chill(void *unused) ...@@ -112,7 +112,7 @@ static int chill(void *unused)
int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
{ {
struct work_struct *sm_work; struct work_struct *sm_work;
int i; int i, ret;
/* Set up initial state. */ /* Set up initial state. */
mutex_lock(&lock); mutex_lock(&lock);
...@@ -137,8 +137,9 @@ int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) ...@@ -137,8 +137,9 @@ int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
/* This will release the thread on our CPU. */ /* This will release the thread on our CPU. */
put_cpu(); put_cpu();
flush_workqueue(stop_machine_wq); flush_workqueue(stop_machine_wq);
ret = active.fnret;
mutex_unlock(&lock); mutex_unlock(&lock);
return active.fnret; return ret;
} }
int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment