From e8f22f76845e08ec838d5198a8c25d207ba52ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 1 Oct 2019 17:04:26 +0100 Subject: cpus: kick all vCPUs when running thread=single MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qemu_cpu_kick is used for a number of reasons including to indicate there is work to be done. However when thread=single the old qemu_cpu_kick_rr_cpu only advanced the vCPU to the next executing one which can lead to a hang in the case that: a) the kick is from outside the vCPUs (e.g. iothread) b) the timers are paused (i.e. iothread calling run_on_cpu) To avoid this lets split qemu_cpu_kick_rr into two functions. One for the timer which continues to advance to the next timeslice and another for all other kicks. Message-Id: <20191001160426.26644-1-alex.bennee@linaro.org> Reviewed-by: Paolo Bonzini Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Signed-off-by: Richard Henderson --- cpus.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'cpus.c') diff --git a/cpus.c b/cpus.c index d2c61ff155..bee7209134 100644 --- a/cpus.c +++ b/cpus.c @@ -949,8 +949,8 @@ static inline int64_t qemu_tcg_next_kick(void) return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD; } -/* Kick the currently round-robin scheduled vCPU */ -static void qemu_cpu_kick_rr_cpu(void) +/* Kick the currently round-robin scheduled vCPU to next */ +static void qemu_cpu_kick_rr_next_cpu(void) { CPUState *cpu; do { @@ -961,6 +961,16 @@ static void qemu_cpu_kick_rr_cpu(void) } while (cpu != atomic_mb_read(&tcg_current_rr_cpu)); } +/* Kick all RR vCPUs */ +static void qemu_cpu_kick_rr_cpus(void) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + cpu_exit(cpu); + }; +} + static void do_nothing(CPUState *cpu, run_on_cpu_data unused) { } @@ -993,7 +1003,7 @@ void qemu_timer_notify_cb(void *opaque, QEMUClockType type) static void kick_tcg_thread(void *opaque) { timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick()); - qemu_cpu_kick_rr_cpu(); + qemu_cpu_kick_rr_next_cpu(); } static void start_tcg_kick_timer(void) @@ -1828,9 +1838,11 @@ void qemu_cpu_kick(CPUState *cpu) { qemu_cond_broadcast(cpu->halt_cond); if (tcg_enabled()) { - cpu_exit(cpu); - /* NOP unless doing single-thread RR */ - qemu_cpu_kick_rr_cpu(); + if (qemu_tcg_mttcg_enabled()) { + cpu_exit(cpu); + } else { + qemu_cpu_kick_rr_cpus(); + } } else { if (hax_enabled()) { /* -- cgit v1.2.3