提交 9102deda 编写于 作者: P Paolo Bonzini

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: NRichard Henderson <rth@twiddle.net>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 aed807c8
...@@ -1090,6 +1090,12 @@ static void qemu_cpu_kick_thread(CPUState *cpu) ...@@ -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) ...@@ -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
......
...@@ -1362,7 +1362,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) ...@@ -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
} }
......
...@@ -214,7 +214,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr, ...@@ -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.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册