Move the respective functions from sysemu to cpu-common. Signed-off-by: Ilya Leoshkevich <i...@linux.ibm.com> --- accel/tcg/user-exec-stub.c | 4 -- accel/tcg/user-exec.c | 11 +++- cpu-common.c | 115 +++++++++++++++++++++++++++++++++++++ include/exec/cpu-common.h | 7 +++ include/sysemu/cpus.h | 5 -- system/cpus.c | 108 ---------------------------------- 6 files changed, 132 insertions(+), 118 deletions(-)
diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c index 4fbe2dbdc88..e79f2e88498 100644 --- a/accel/tcg/user-exec-stub.c +++ b/accel/tcg/user-exec-stub.c @@ -2,10 +2,6 @@ #include "hw/core/cpu.h" #include "exec/replay-core.h" -void cpu_resume(CPUState *cpu) -{ -} - void cpu_remove_sync(CPUState *cpu) { } diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index de4753cded7..3399b074485 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -1293,12 +1293,19 @@ int cpu_exec_user(CPUState *cs) { int trapnr; + do { + qemu_wait_io_event(cs); + } while (!cpu_can_run(cs)); + bql_unlock(); cpu_exec_start(cs); trapnr = cpu_exec(cs); cpu_exec_end(cs); bql_lock(); - process_queued_cpu_work(cs); + + do { + qemu_wait_io_event(cs); + } while (!cpu_can_run(cs)); return trapnr; } @@ -1306,11 +1313,13 @@ int cpu_exec_user(CPUState *cs) void qemu_cpu_kick(CPUState *cpu) { cpu_exit(cpu); + qemu_cond_broadcast(cpu->halt_cond); } void cpu_enter_syscall(CPUState *cs) { cs->in_syscall = true; + qemu_pause_cond_broadcast(); } void cpu_exit_syscall(CPUState *cs) diff --git a/cpu-common.c b/cpu-common.c index 2822ee9373d..979e3fe8806 100644 --- a/cpu-common.c +++ b/cpu-common.c @@ -24,6 +24,8 @@ #include "sysemu/cpus.h" #include "qemu/lockable.h" #include "trace/trace-root.h" +#include "exec/replay-core.h" +#include "qemu/plugin.h" QemuMutex qemu_cpu_list_lock; static QemuCond exclusive_cond; @@ -456,6 +458,9 @@ void cpu_breakpoint_remove_all(CPUState *cpu, int mask) /* The Big QEMU Lock (BQL) */ static QemuMutex bql = QEMU_MUTEX_INITIALIZER; +/* system init */ +static QemuCond qemu_pause_cond = QEMU_COND_INITIALIZER; + QEMU_DEFINE_STATIC_CO_TLS(bool, bql_locked) bool bql_locked(void) @@ -498,6 +503,105 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data) do_run_on_cpu(cpu, func, data, &bql); } +static bool all_vcpus_paused(void) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + if (!cpu_is_paused(cpu)) { + return false; + } + } + + return true; +} + +void pause_all_vcpus(void) +{ + CPUState *cpu; + + qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false); + CPU_FOREACH(cpu) { + cpu_pause(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()) { + qemu_cond_wait_bql(&qemu_pause_cond); + CPU_FOREACH(cpu) { + qemu_cpu_kick(cpu); + } + } + + bql_unlock(); + replay_mutex_lock(); + bql_lock(); +} + +void qemu_pause_cond_broadcast(void) +{ + qemu_cond_broadcast(&qemu_pause_cond); +} + +static void qemu_cpu_stop(CPUState *cpu, bool exit) +{ + g_assert(qemu_cpu_is_self(cpu)); + cpu->stop = false; + cpu->stopped = true; + if (exit) { + cpu_exit(cpu); + } + qemu_pause_cond_broadcast(); +} + +void qemu_wait_io_event_common(CPUState *cpu) +{ + qatomic_set_mb(&cpu->thread_kicked, false); + if (cpu->stop) { + qemu_cpu_stop(cpu, false); + } + process_queued_cpu_work(cpu); +} + +void qemu_wait_io_event(CPUState *cpu) +{ + bool slept = false; + + while (cpu_thread_is_idle(cpu)) { + if (!slept) { + slept = true; + qemu_plugin_vcpu_idle_cb(cpu); + } + qemu_cond_wait_bql(cpu->halt_cond); + } + if (slept) { + qemu_plugin_vcpu_resume_cb(cpu); + } + + qemu_wait_io_event_common(cpu); +} + +void cpu_pause(CPUState *cpu) +{ + if (qemu_cpu_is_self(cpu)) { + qemu_cpu_stop(cpu, true); + } else { + cpu->stop = true; + qemu_cpu_kick(cpu); + } +} + +void cpu_resume(CPUState *cpu) +{ + cpu->stop = false; + cpu->stopped = false; + qemu_cpu_kick(cpu); +} + bool cpu_work_list_empty(CPUState *cpu) { return QSIMPLEQ_EMPTY_ATOMIC(&cpu->work_list); @@ -516,3 +620,14 @@ int cpu_thread_is_idle_common(CPUState *cpu) } return -1; } + +bool cpu_can_run(CPUState *cpu) +{ + if (cpu->stop) { + return false; + } + if (cpu_is_stopped(cpu)) { + return false; + } + return true; +} diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index e8b530ed889..a54368c5b69 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -234,6 +234,13 @@ void cpu_exit_syscall(CPUState *cs); int cpu_thread_is_idle_common(CPUState *cpu); bool cpu_thread_is_idle(CPUState *cpu); bool cpu_is_paused(CPUState *cpu); +bool cpu_can_run(CPUState *cpu); +void qemu_wait_io_event_common(CPUState *cpu); +void qemu_wait_io_event(CPUState *cpu); +void pause_all_vcpus(void); +void qemu_pause_cond_broadcast(void); +bool cpu_work_list_empty(CPUState *cpu); + /** * env_archcpu(env) diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index bfa3fd45650..ebfd0b77bcd 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -20,11 +20,7 @@ void dummy_start_vcpu_thread(CPUState *); #define VCPU_THREAD_NAME_SIZE 16 void cpus_kick_thread(CPUState *cpu); -bool cpu_work_list_empty(CPUState *cpu); bool all_cpu_threads_idle(void); -bool cpu_can_run(CPUState *cpu); -void qemu_wait_io_event_common(CPUState *cpu); -void qemu_wait_io_event(CPUState *cpu); void cpu_thread_signal_created(CPUState *cpu); void cpu_thread_signal_destroyed(CPUState *cpu); void cpu_handle_guest_debug(CPUState *cpu); @@ -34,7 +30,6 @@ void cpu_handle_guest_debug(CPUState *cpu); bool qemu_in_vcpu_thread(void); void qemu_init_cpu_loop(void); void resume_all_vcpus(void); -void pause_all_vcpus(void); void cpu_stop_current(void); extern int icount_align_option; diff --git a/system/cpus.c b/system/cpus.c index 407140c41f6..9ad7bae056e 100644 --- a/system/cpus.c +++ b/system/cpus.c @@ -307,17 +307,6 @@ int vm_shutdown(void) return do_vm_stop(RUN_STATE_SHUTDOWN, false); } -bool cpu_can_run(CPUState *cpu) -{ - if (cpu->stop) { - return false; - } - if (cpu_is_stopped(cpu)) { - return false; - } - return true; -} - void cpu_handle_guest_debug(CPUState *cpu) { if (replay_running_debug()) { @@ -400,56 +389,15 @@ static QemuThread io_thread; /* cpu creation */ static QemuCond qemu_cpu_cond; -/* system init */ -static QemuCond qemu_pause_cond; void qemu_init_cpu_loop(void) { qemu_init_sigbus(); qemu_cond_init(&qemu_cpu_cond); - qemu_cond_init(&qemu_pause_cond); qemu_thread_get_self(&io_thread); } -static void qemu_cpu_stop(CPUState *cpu, bool exit) -{ - g_assert(qemu_cpu_is_self(cpu)); - cpu->stop = false; - cpu->stopped = true; - if (exit) { - cpu_exit(cpu); - } - qemu_cond_broadcast(&qemu_pause_cond); -} - -void qemu_wait_io_event_common(CPUState *cpu) -{ - qatomic_set_mb(&cpu->thread_kicked, false); - if (cpu->stop) { - qemu_cpu_stop(cpu, false); - } - process_queued_cpu_work(cpu); -} - -void qemu_wait_io_event(CPUState *cpu) -{ - bool slept = false; - - while (cpu_thread_is_idle(cpu)) { - if (!slept) { - slept = true; - qemu_plugin_vcpu_idle_cb(cpu); - } - qemu_cond_wait_bql(cpu->halt_cond); - } - if (slept) { - qemu_plugin_vcpu_resume_cb(cpu); - } - - qemu_wait_io_event_common(cpu); -} - void cpus_kick_thread(CPUState *cpu) { if (cpu->thread_kicked) { @@ -513,67 +461,11 @@ void cpu_thread_signal_destroyed(CPUState *cpu) qemu_cond_signal(&qemu_cpu_cond); } -void cpu_pause(CPUState *cpu) -{ - if (qemu_cpu_is_self(cpu)) { - qemu_cpu_stop(cpu, true); - } else { - cpu->stop = true; - qemu_cpu_kick(cpu); - } -} - -void cpu_resume(CPUState *cpu) -{ - cpu->stop = false; - cpu->stopped = false; - qemu_cpu_kick(cpu); -} - bool cpu_is_paused(CPUState *cpu) { return cpu->stopped; } -static bool all_vcpus_paused(void) -{ - CPUState *cpu; - - CPU_FOREACH(cpu) { - if (!cpu_is_paused(cpu)) { - return false; - } - } - - return true; -} - -void pause_all_vcpus(void) -{ - CPUState *cpu; - - qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false); - CPU_FOREACH(cpu) { - cpu_pause(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()) { - qemu_cond_wait_bql(&qemu_pause_cond); - CPU_FOREACH(cpu) { - qemu_cpu_kick(cpu); - } - } - - bql_unlock(); - replay_mutex_lock(); - bql_lock(); -} - void resume_all_vcpus(void) { CPUState *cpu; -- 2.46.0