Browse Source

accel/tcg: create a thread-kick function for TCG

Round-robin TCG is calling into cpu_exit() directly.  In preparation
for making cpu_exit() usable from all accelerators, define a generic
thread-kick function for TCG which is used directly in the multi-threaded
case, and through CPU_FOREACH in the round-robin case.

Use it also for user-mode emulation, and take the occasion to move
the implementation to accel/tcg/user-exec.c.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
pull/305/head
Paolo Bonzini 1 year ago
parent
commit
9cf342b491
  1. 6
      accel/tcg/cpu-exec.c
  2. 5
      accel/tcg/tcg-accel-ops-mttcg.c
  3. 3
      accel/tcg/tcg-accel-ops-mttcg.h
  4. 2
      accel/tcg/tcg-accel-ops-rr.c
  5. 2
      accel/tcg/tcg-accel-ops.c
  6. 1
      accel/tcg/tcg-accel-ops.h
  7. 6
      accel/tcg/user-exec.c
  8. 5
      bsd-user/main.c
  9. 2
      docs/devel/tcg-icount.rst
  10. 5
      linux-user/main.c

6
accel/tcg/cpu-exec.c

@ -40,6 +40,7 @@
#include "exec/replay-core.h"
#include "system/tcg.h"
#include "exec/helper-proto-common.h"
#include "tcg-accel-ops.h"
#include "tb-jmp-cache.h"
#include "tb-hash.h"
#include "tb-context.h"
@ -748,6 +749,11 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
return false;
}
void tcg_kick_vcpu_thread(CPUState *cpu)
{
cpu_exit(cpu);
}
static inline bool icount_exit_request(CPUState *cpu)
{
if (!icount_enabled()) {

5
accel/tcg/tcg-accel-ops-mttcg.c

@ -123,11 +123,6 @@ static void *mttcg_cpu_thread_fn(void *arg)
return NULL;
}
void mttcg_kick_vcpu_thread(CPUState *cpu)
{
cpu_exit(cpu);
}
void mttcg_start_vcpu_thread(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];

3
accel/tcg/tcg-accel-ops-mttcg.h

@ -10,9 +10,6 @@
#ifndef TCG_ACCEL_OPS_MTTCG_H
#define TCG_ACCEL_OPS_MTTCG_H
/* kick MTTCG vCPU thread */
void mttcg_kick_vcpu_thread(CPUState *cpu);
/* start an mttcg vCPU thread */
void mttcg_start_vcpu_thread(CPUState *cpu);

2
accel/tcg/tcg-accel-ops-rr.c

@ -43,7 +43,7 @@ void rr_kick_vcpu_thread(CPUState *unused)
CPUState *cpu;
CPU_FOREACH(cpu) {
cpu_exit(cpu);
tcg_kick_vcpu_thread(cpu);
};
}

2
accel/tcg/tcg-accel-ops.c

@ -206,7 +206,7 @@ static void tcg_accel_ops_init(AccelClass *ac)
if (qemu_tcg_mttcg_enabled()) {
ops->create_vcpu_thread = mttcg_start_vcpu_thread;
ops->kick_vcpu_thread = mttcg_kick_vcpu_thread;
ops->kick_vcpu_thread = tcg_kick_vcpu_thread;
ops->handle_interrupt = tcg_handle_interrupt;
} else {
ops->create_vcpu_thread = rr_start_vcpu_thread;

1
accel/tcg/tcg-accel-ops.h

@ -18,5 +18,6 @@ void tcg_cpu_destroy(CPUState *cpu);
int tcg_cpu_exec(CPUState *cpu);
void tcg_handle_interrupt(CPUState *cpu, int mask);
void tcg_cpu_init_cflags(CPUState *cpu, bool parallel);
void tcg_kick_vcpu_thread(CPUState *cpu);
#endif /* TCG_ACCEL_OPS_H */

6
accel/tcg/user-exec.c

@ -38,6 +38,7 @@
#include "qemu/int128.h"
#include "trace.h"
#include "tcg/tcg-ldst.h"
#include "tcg-accel-ops.h"
#include "backend-ldst.h"
#include "internal-common.h"
#include "tb-internal.h"
@ -46,6 +47,11 @@ __thread uintptr_t helper_retaddr;
//#define DEBUG_SIGNAL
void qemu_cpu_kick(CPUState *cpu)
{
tcg_kick_vcpu_thread(cpu);
}
/*
* Adjust the pc to pass to cpu_restore_state; return the memop type.
*/

5
bsd-user/main.c

@ -214,11 +214,6 @@ bool qemu_cpu_is_self(CPUState *cpu)
return thread_cpu == cpu;
}
void qemu_cpu_kick(CPUState *cpu)
{
cpu_exit(cpu);
}
/* Assumes contents are already zeroed. */
static void init_task_state(TaskState *ts)
{

2
docs/devel/tcg-icount.rst

@ -37,7 +37,7 @@ translator starts by allocating a budget of instructions to be
executed. The budget of instructions is limited by how long it will be
until the next timer will expire. We store this budget as part of a
vCPU icount_decr field which shared with the machinery for handling
cpu_exit(). The whole field is checked at the start of every
qemu_cpu_kick(). The whole field is checked at the start of every
translated block and will cause a return to the outer loop to deal
with whatever caused the exit.

5
linux-user/main.c

@ -189,11 +189,6 @@ bool qemu_cpu_is_self(CPUState *cpu)
return thread_cpu == cpu;
}
void qemu_cpu_kick(CPUState *cpu)
{
cpu_exit(cpu);
}
void task_settid(TaskState *ts)
{
if (ts->ts_tid == 0) {

Loading…
Cancel
Save