mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
cpu: sync any remaining RCU callbacks before CPU up/down
During CPU down operation RCU callbacks are scheduled to finish off some actions later as soon as CPU is fully dead (the same applies to CPU up operation in case error path is taken). If in the same grace period another CPU up operation is performed on the same CPU, RCU callback will be called later on a CPU in a potentially wrong (already up again instead of still being down) state leading to eventual state inconsistency and/or crash. In order to avoid it - flush RCU callbacks explicitly before starting the next CPU up/down operation. Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com> Reviewed-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
a6fe79a597
commit
540d4d6037
3 files changed
+4
-9
No files matched your search
@@ -306,7 +306,6 @@ static int enter_state(u32 state)
|
||||
cpufreq_add_cpu(0);
|
||||
|
||||
enable_cpu:
|
||||
rcu_barrier();
|
||||
mtrr_aps_sync_begin();
|
||||
enable_nonboot_cpus();
|
||||
mtrr_aps_sync_end();
|
||||
|
||||
@@ -84,12 +84,9 @@ long cpu_up_helper(void *data)
|
||||
unsigned int cpu = (unsigned long)data;
|
||||
int ret = cpu_up(cpu);
|
||||
|
||||
/* Have one more go on EBUSY. */
|
||||
if ( ret == -EBUSY )
|
||||
{
|
||||
/* On EBUSY, flush RCU work and have one more go. */
|
||||
rcu_barrier();
|
||||
ret = cpu_up(cpu);
|
||||
}
|
||||
|
||||
if ( !ret && !opt_smt &&
|
||||
cpu_data[cpu].compute_unit_id == INVALID_CUID &&
|
||||
@@ -109,12 +106,9 @@ long cpu_down_helper(void *data)
|
||||
{
|
||||
int cpu = (unsigned long)data;
|
||||
int ret = cpu_down(cpu);
|
||||
/* Have one more go on EBUSY. */
|
||||
if ( ret == -EBUSY )
|
||||
{
|
||||
/* On EBUSY, flush RCU work and have one more go. */
|
||||
rcu_barrier();
|
||||
ret = cpu_down(cpu);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xen/init.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/stop_machine.h>
|
||||
#include <xen/rcupdate.h>
|
||||
|
||||
unsigned int __read_mostly nr_cpu_ids = NR_CPUS;
|
||||
#ifndef nr_cpumask_bits
|
||||
@@ -53,6 +54,7 @@ void put_cpu_maps(void)
|
||||
|
||||
void cpu_hotplug_begin(void)
|
||||
{
|
||||
rcu_barrier();
|
||||
write_lock(&cpu_add_remove_lock);
|
||||
}
|
||||
|
||||
|
||||