stop_machine: fix error code handling on multiple cpus
Using |= for updating a value which might be updated on several cpus concurrently will not always work since we need to make sure that the update happens atomically. To fix this just use a write if the called function returns an error code on a cpu. We end up writing the error code of an arbitrary cpu if multiple ones fail but that should be sufficient. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Родитель
c9583e55fa
Коммит
8163bcac77
|
@ -66,6 +66,7 @@ static void stop_cpu(struct work_struct *unused)
|
||||||
enum stopmachine_state curstate = STOPMACHINE_NONE;
|
enum stopmachine_state curstate = STOPMACHINE_NONE;
|
||||||
struct stop_machine_data *smdata = &idle;
|
struct stop_machine_data *smdata = &idle;
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
int err;
|
||||||
|
|
||||||
if (!active_cpus) {
|
if (!active_cpus) {
|
||||||
if (cpu == first_cpu(cpu_online_map))
|
if (cpu == first_cpu(cpu_online_map))
|
||||||
|
@ -86,9 +87,11 @@ static void stop_cpu(struct work_struct *unused)
|
||||||
hard_irq_disable();
|
hard_irq_disable();
|
||||||
break;
|
break;
|
||||||
case STOPMACHINE_RUN:
|
case STOPMACHINE_RUN:
|
||||||
/* |= allows error detection if functions on
|
/* On multiple CPUs only a single error code
|
||||||
* multiple CPUs. */
|
* is needed to tell that something failed. */
|
||||||
smdata->fnret |= smdata->fn(smdata->data);
|
err = smdata->fn(smdata->data);
|
||||||
|
if (err)
|
||||||
|
smdata->fnret = err;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче