use qemu_cpu_kick instead of cpu_exit or qemu_cpu_kick_thread

Use the same API to trigger interruption of a CPU, no matter if
under TCG or KVM.  There is no difference: these calls come from
the CPU thread, so the qemu_cpu_kick calls will send a signal
to the running thread and it will be processed synchronously,
just like a call to cpu_exit.  The only difference is in the
overhead, but neither call to cpu_exit (now qemu_cpu_kick)
is in a hot path.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2015-08-18 06:52:09 -07:00
parent aed807c8e2
commit 9102dedaa1
3 changed files with 10 additions and 11 deletions

17
cpus.c
View File

@ -1090,6 +1090,12 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
#ifndef _WIN32 #ifndef _WIN32
int err; int err;
if (!tcg_enabled()) {
if (cpu->thread_kicked) {
return;
}
cpu->thread_kicked = true;
}
err = pthread_kill(cpu->thread->thread, SIG_IPI); err = pthread_kill(cpu->thread->thread, SIG_IPI);
if (err) { if (err) {
fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
@ -1127,21 +1133,14 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
void qemu_cpu_kick(CPUState *cpu) void qemu_cpu_kick(CPUState *cpu)
{ {
qemu_cond_broadcast(cpu->halt_cond); qemu_cond_broadcast(cpu->halt_cond);
if (!tcg_enabled() && !cpu->thread_kicked) { qemu_cpu_kick_thread(cpu);
qemu_cpu_kick_thread(cpu);
cpu->thread_kicked = true;
}
} }
void qemu_cpu_kick_self(void) void qemu_cpu_kick_self(void)
{ {
#ifndef _WIN32 #ifndef _WIN32
assert(current_cpu); assert(current_cpu);
qemu_cpu_kick_thread(current_cpu);
if (!current_cpu->thread_kicked) {
qemu_cpu_kick_thread(current_cpu);
current_cpu->thread_kicked = true;
}
#else #else
abort(); abort();
#endif #endif

View File

@ -1362,7 +1362,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
is still in the running state, which can cause packets to be dropped is still in the running state, which can cause packets to be dropped
and state transition 'T' packets to be sent while the syscall is still and state transition 'T' packets to be sent while the syscall is still
being processed. */ being processed. */
cpu_exit(s->c_cpu); qemu_cpu_kick(s->c_cpu);
#endif #endif
} }

View File

@ -214,7 +214,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr,
CPUPPCState *env = &cpu->env; CPUPPCState *env = &cpu->env;
cs->halted = 1; cs->halted = 1;
cpu_exit(cs); qemu_cpu_kick(cs);
/* /*
* While stopping a CPU, the guest calls H_CPPR which * While stopping a CPU, the guest calls H_CPPR which
* effectively disables interrupts on XICS level. * effectively disables interrupts on XICS level.