+6
-4
kernel/stop_machine.c
+6
-4
kernel/stop_machine.c
···
7
7
* Copyright (C) 2010 SUSE Linux Products GmbH
8
8
* Copyright (C) 2010 Tejun Heo <tj@kernel.org>
9
9
*/
10
+
#include <linux/compiler.h>
10
11
#include <linux/completion.h>
11
12
#include <linux/cpu.h>
12
13
#include <linux/init.h>
···
168
167
/* Reset ack counter. */
169
168
atomic_set(&msdata->thread_ack, msdata->num_threads);
170
169
smp_wmb();
171
-
msdata->state = newstate;
170
+
WRITE_ONCE(msdata->state, newstate);
172
171
}
173
172
174
173
/* Last one to ack a state moves to the next state. */
···
187
186
static int multi_cpu_stop(void *data)
188
187
{
189
188
struct multi_stop_data *msdata = data;
190
-
enum multi_stop_state curstate = MULTI_STOP_NONE;
189
+
enum multi_stop_state newstate, curstate = MULTI_STOP_NONE;
191
190
int cpu = smp_processor_id(), err = 0;
192
191
const struct cpumask *cpumask;
193
192
unsigned long flags;
···
211
210
do {
212
211
/* Chill out and ensure we re-read multi_stop_state. */
213
212
stop_machine_yield(cpumask);
214
-
if (msdata->state != curstate) {
215
-
curstate = msdata->state;
213
+
newstate = READ_ONCE(msdata->state);
214
+
if (newstate != curstate) {
215
+
curstate = newstate;
216
216
switch (curstate) {
217
217
case MULTI_STOP_DISABLE_IRQ:
218
218
local_irq_disable();