mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
tcg: drop global lock during TCG code execution
This finally allows TCG to benefit from the iothread introduction: Drop the global mutex while running pure TCG CPU code. Reacquire the lock when entering MMIO or PIO emulation, or when leaving the TCG loop. We have to revert a few optimization for the current TCG threading model, namely kicking the TCG thread in qemu_mutex_lock_iothread and not kicking it in qemu_cpu_kick. We also need to disable RAM block reordering until we have a more efficient locking mechanism at hand. Still, a Linux x86 UP guest and my Musicpal ARM model boot fine here. These numbers demonstrate where we gain something: 20338 jan 20 0 331m 75m 6904 R 99 0.9 0:50.95 qemu-system-arm 20337 jan 20 0 331m 75m 6904 S 20 0.9 0:26.50 qemu-system-arm The guest CPU was fully loaded, but the iothread could still run mostly independent on a second core. Without the patch we don't get beyond 32206 jan 20 0 330m 73m 7036 R 82 0.9 1:06.00 qemu-system-arm 32204 jan 20 0 330m 73m 7036 S 21 0.9 0:17.03 qemu-system-arm We don't benefit significantly, though, when the guest is not fully loading a host CPU. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Message-Id: <1439220437-23957-10-git-send-email-fred.konrad@greensocs.com> [FK: Rebase, fix qemu_devices_reset deadlock, rm address_space_* mutex] Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com> [EGC: fixed iothread lock for cpu-exec IRQ handling] Signed-off-by: Emilio G. Cota <cota@braap.org> [AJB: -smp single-threaded fix, clean commit msg, BQL fixes] Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <rth@twiddle.net> Reviewed-by: Pranith Kumar <bobby.prani@gmail.com> [PM: target-arm changes] Acked-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
791158d93b
commit
8d04fb55de
18 changed files with 166 additions and 49 deletions
28
cpus.c
28
cpus.c
|
@ -1027,8 +1027,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *cpu)
|
|||
#endif /* _WIN32 */
|
||||
|
||||
static QemuMutex qemu_global_mutex;
|
||||
static QemuCond qemu_io_proceeded_cond;
|
||||
static unsigned iothread_requesting_mutex;
|
||||
|
||||
static QemuThread io_thread;
|
||||
|
||||
|
@ -1042,7 +1040,6 @@ void qemu_init_cpu_loop(void)
|
|||
qemu_init_sigbus();
|
||||
qemu_cond_init(&qemu_cpu_cond);
|
||||
qemu_cond_init(&qemu_pause_cond);
|
||||
qemu_cond_init(&qemu_io_proceeded_cond);
|
||||
qemu_mutex_init(&qemu_global_mutex);
|
||||
|
||||
qemu_thread_get_self(&io_thread);
|
||||
|
@ -1085,10 +1082,6 @@ static void qemu_tcg_wait_io_event(CPUState *cpu)
|
|||
|
||||
start_tcg_kick_timer();
|
||||
|
||||
while (iothread_requesting_mutex) {
|
||||
qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
|
||||
}
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
qemu_wait_io_event_common(cpu);
|
||||
}
|
||||
|
@ -1249,9 +1242,11 @@ static int tcg_cpu_exec(CPUState *cpu)
|
|||
cpu->icount_decr.u16.low = decr;
|
||||
cpu->icount_extra = count;
|
||||
}
|
||||
qemu_mutex_unlock_iothread();
|
||||
cpu_exec_start(cpu);
|
||||
ret = cpu_exec(cpu);
|
||||
cpu_exec_end(cpu);
|
||||
qemu_mutex_lock_iothread();
|
||||
#ifdef CONFIG_PROFILER
|
||||
tcg_time += profile_getclock() - ti;
|
||||
#endif
|
||||
|
@ -1479,27 +1474,14 @@ bool qemu_mutex_iothread_locked(void)
|
|||
|
||||
void qemu_mutex_lock_iothread(void)
|
||||
{
|
||||
atomic_inc(&iothread_requesting_mutex);
|
||||
/* In the simple case there is no need to bump the VCPU thread out of
|
||||
* TCG code execution.
|
||||
*/
|
||||
if (!tcg_enabled() || qemu_in_vcpu_thread() ||
|
||||
!first_cpu || !first_cpu->created) {
|
||||
qemu_mutex_lock(&qemu_global_mutex);
|
||||
atomic_dec(&iothread_requesting_mutex);
|
||||
} else {
|
||||
if (qemu_mutex_trylock(&qemu_global_mutex)) {
|
||||
qemu_cpu_kick_rr_cpu();
|
||||
qemu_mutex_lock(&qemu_global_mutex);
|
||||
}
|
||||
atomic_dec(&iothread_requesting_mutex);
|
||||
qemu_cond_broadcast(&qemu_io_proceeded_cond);
|
||||
}
|
||||
g_assert(!qemu_mutex_iothread_locked());
|
||||
qemu_mutex_lock(&qemu_global_mutex);
|
||||
iothread_locked = true;
|
||||
}
|
||||
|
||||
void qemu_mutex_unlock_iothread(void)
|
||||
{
|
||||
g_assert(qemu_mutex_iothread_locked());
|
||||
iothread_locked = false;
|
||||
qemu_mutex_unlock(&qemu_global_mutex);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue