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