From: Tobin Feldman-Fitzthum <tobin@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 <dovmurik@linux.vnet.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.vnet.ibm.com>
Signed-off-by: Tobin Feldman-Fitzthum <tobin@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