From: Tobin Feldman-Fitzthum <to...@linux.ibm.com> Introduce a function to pause all CPUs except the auxiliary CPUs. This will be used during migration when a migration handler is running on the auxiliary CPU.
Co-Author: Dov Murik <dovmu...@linux.vnet.ibm.com> Signed-off-by: Dov Murik <dovmu...@linux.vnet.ibm.com> Signed-off-by: Tobin Feldman-Fitzthum <to...@linux.ibm.com> --- include/sysemu/cpus.h | 1 + softmmu/cpus.c | 53 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index dc24e38254..e668570053 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -34,6 +34,7 @@ bool qemu_in_vcpu_thread(void); void qemu_init_cpu_loop(void); void resume_all_vcpus(void); void pause_all_vcpus(void); +void pause_all_vcpus_except_aux(void); void cpu_stop_current(void); extern int icount_align_option; diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 68fa4639a7..3028b5d0d4 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -550,6 +550,19 @@ static bool all_vcpus_paused(void) return true; } +static bool all_vcpus_except_aux_paused(void) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + if (!cpu->aux && !cpu->stopped) { + return false; + } + } + + return true; +} + void pause_all_vcpus(void) { CPUState *cpu; @@ -564,15 +577,51 @@ void pause_all_vcpus(void) } } + /* + * Drop the replay_lock so any vCPU threads woken up can finish their + * replay tasks + */ + replay_mutex_unlock(); + + while (!all_vcpus_paused()) { + qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); + CPU_FOREACH(cpu) { + qemu_cpu_kick(cpu); + } + } + + qemu_mutex_unlock_iothread(); + replay_mutex_lock(); + qemu_mutex_lock_iothread(); +} + +void pause_all_vcpus_except_aux(void) +{ + CPUState *cpu; + + qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false); + CPU_FOREACH(cpu) { + if (!cpu->aux) { + if (qemu_cpu_is_self(cpu)) { + qemu_cpu_stop(cpu, true); + } else { + cpu->stop = true; + qemu_cpu_kick(cpu); + } + } + } + /* We need to drop the replay_lock so any vCPU threads woken up * can finish their replay tasks */ replay_mutex_unlock(); - while (!all_vcpus_paused()) { + while (!all_vcpus_except_aux_paused()) { qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); CPU_FOREACH(cpu) { - qemu_cpu_kick(cpu); + if (!cpu->aux) { + qemu_cpu_kick(cpu); + } } } -- 2.20.1