Commit 589f1222 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 531e93d1 b1fc5833
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright (C) 2010 SUSE Linux Products GmbH * Copyright (C) 2010 SUSE Linux Products GmbH
* Copyright (C) 2010 Tejun Heo <tj@kernel.org> * Copyright (C) 2010 Tejun Heo <tj@kernel.org>
*/ */
#include <linux/compiler.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -167,7 +168,7 @@ static void set_state(struct multi_stop_data *msdata, ...@@ -167,7 +168,7 @@ static void set_state(struct multi_stop_data *msdata,
/* Reset ack counter. */ /* Reset ack counter. */
atomic_set(&msdata->thread_ack, msdata->num_threads); atomic_set(&msdata->thread_ack, msdata->num_threads);
smp_wmb(); smp_wmb();
msdata->state = newstate; WRITE_ONCE(msdata->state, newstate);
} }
/* Last one to ack a state moves to the next state. */ /* Last one to ack a state moves to the next state. */
...@@ -186,7 +187,7 @@ void __weak stop_machine_yield(const struct cpumask *cpumask) ...@@ -186,7 +187,7 @@ void __weak stop_machine_yield(const struct cpumask *cpumask)
static int multi_cpu_stop(void *data) static int multi_cpu_stop(void *data)
{ {
struct multi_stop_data *msdata = data; struct multi_stop_data *msdata = data;
enum multi_stop_state curstate = MULTI_STOP_NONE; enum multi_stop_state newstate, curstate = MULTI_STOP_NONE;
int cpu = smp_processor_id(), err = 0; int cpu = smp_processor_id(), err = 0;
const struct cpumask *cpumask; const struct cpumask *cpumask;
unsigned long flags; unsigned long flags;
...@@ -210,8 +211,9 @@ static int multi_cpu_stop(void *data) ...@@ -210,8 +211,9 @@ static int multi_cpu_stop(void *data)
do { do {
/* Chill out and ensure we re-read multi_stop_state. */ /* Chill out and ensure we re-read multi_stop_state. */
stop_machine_yield(cpumask); stop_machine_yield(cpumask);
if (msdata->state != curstate) { newstate = READ_ONCE(msdata->state);
curstate = msdata->state; if (newstate != curstate) {
curstate = newstate;
switch (curstate) { switch (curstate) {
case MULTI_STOP_DISABLE_IRQ: case MULTI_STOP_DISABLE_IRQ:
local_irq_disable(); local_irq_disable();
......
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