History

Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull stop-machine fix from Thomas Gleixner: "A single fix, amending stop machine with WRITE/READ_ONCE() to address the fallout of KCSAN" * 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: stop_machine: Avoid potential race behaviour

Linus Torvalds committed 7 years ago

Commit 589f1222 parents 531e93d b1fc5831 file · +6 −4Browse files

Unified · Split

kernel/stop_machine.c+6−4
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 * Copyright (C) 2010 SUSE Linux Products GmbH
88 * Copyright (C) 2010 Tejun Heo <tj@kernel.org>
99 */
10+#include <linux/compiler.h>
1011 #include <linux/completion.h>
1112 #include <linux/cpu.h>
1213 #include <linux/init.h>
@@ -167,7 +168,7 @@ static void set_state(struct multi_stop_data *msdata, · 154 unmodified lines
167168 /* Reset ack counter. */
168169 atomic_set(&msdata->thread_ack, msdata->num_threads);
169170 smp_wmb();
170− msdata->state = newstate;
171+ WRITE_ONCE(msdata->state, newstate);
171172 }
172173
173174 /* Last one to ack a state moves to the next state. */
@@ -186,7 +187,7 @@ void __weak stop_machine_yield(const struct cpumask *cpumask) · 12 unmodified lines
186187 static int multi_cpu_stop(void *data)
187188 {
188189 struct multi_stop_data *msdata = data;
189− enum multi_stop_state curstate = MULTI_STOP_NONE;
190+ enum multi_stop_state newstate, curstate = MULTI_STOP_NONE;
190191 int cpu = smp_processor_id(), err = 0;
191192 const struct cpumask *cpumask;
192193 unsigned long flags;
@@ -210,8 +211,9 @@ static int multi_cpu_stop(void *data) · 17 unmodified lines
210211 do {
211212 /* Chill out and ensure we re-read multi_stop_state. */
212213 stop_machine_yield(cpumask);
213− if (msdata->state != curstate) {
214− curstate = msdata->state;
214+ newstate = READ_ONCE(msdata->state);
215+ if (newstate != curstate) {
216+ curstate = newstate;
215217 switch (curstate) {
216218 case MULTI_STOP_DISABLE_IRQ:
217219 local_irq_disable();