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: Rusty Russell <rusty@rustcorp.com.au>
Tested-by: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Rusty Russell and committed by Linus Torvalds e14c8bf8 5c06fe77

+3 -2
+3 -2
kernel/stop_machine.c
··· 112 int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) 113 { 114 struct work_struct *sm_work; 115 - int i; 116 117 /* Set up initial state. */ 118 mutex_lock(&lock); ··· 137 /* This will release the thread on our CPU. */ 138 put_cpu(); 139 flush_workqueue(stop_machine_wq); 140 mutex_unlock(&lock); 141 - return active.fnret; 142 } 143 144 int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
··· 112 int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus) 113 { 114 struct work_struct *sm_work; 115 + int i, ret; 116 117 /* Set up initial state. */ 118 mutex_lock(&lock); ··· 137 /* This will release the thread on our CPU. */ 138 put_cpu(); 139 flush_workqueue(stop_machine_wq); 140 + ret = active.fnret; 141 mutex_unlock(&lock); 142 + return ret; 143 } 144 145 int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)