[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC v4 12/28] tcg: cpus rm tcg_exec_all()
From: |
Alex Bennée |
Subject: |
[Qemu-devel] [RFC v4 12/28] tcg: cpus rm tcg_exec_all() |
Date: |
Thu, 11 Aug 2016 16:24:08 +0100 |
In preparation for multi-threaded TCG we remove tcg_exec_all and move
all the CPU cycling into the main thread function. When MTTCG is enabled
we shall use a separate thread function which only handles one vCPU.
Signed-off-by: Alex Bennée <address@hidden>
Reviewed-by: Sergey Fedorov <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
---
v2
- update timer calls to new API on rebase
v3
- move tcg_cpu_exec above thread function, drop static fwd declaration
v4
- split mechanical moves into earlier patch
- moved unplug logic info function, don't break smp boot
---
cpus.c | 89 +++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 45 insertions(+), 44 deletions(-)
diff --git a/cpus.c b/cpus.c
index 0759a84..0ff51ea 100644
--- a/cpus.c
+++ b/cpus.c
@@ -69,7 +69,6 @@
#endif /* CONFIG_LINUX */
-static CPUState *next_cpu;
int64_t max_delay;
int64_t max_advance;
@@ -1129,46 +1128,26 @@ static int tcg_cpu_exec(CPUState *cpu)
return ret;
}
-static void tcg_exec_all(void)
+/* Destroy any remaining vCPUs which have been unplugged and have
+ * finished running
+ */
+static void deal_with_unplugged_cpus(void)
{
- int r;
-
- /* Account partial waits to QEMU_CLOCK_VIRTUAL. */
- qemu_account_warp_timer();
-
- if (next_cpu == NULL) {
- next_cpu = first_cpu;
- }
- for (; next_cpu != NULL && !exit_request; next_cpu = CPU_NEXT(next_cpu)) {
- CPUState *cpu = next_cpu;
-
- qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
- (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
+ CPUState *cpu;
- if (cpu_can_run(cpu)) {
- tcg_cpu_exec_start(cpu);
- r = tcg_cpu_exec(cpu);
- tcg_cpu_exec_end(cpu);
- if (r == EXCP_DEBUG) {
- cpu_handle_guest_debug(cpu);
- break;
- }
- } else if (cpu->stop || cpu->stopped) {
- if (cpu->unplug) {
- next_cpu = CPU_NEXT(cpu);
- }
+ CPU_FOREACH(cpu) {
+ if (cpu->unplug && !cpu_can_run(cpu)) {
+ qemu_tcg_destroy_vcpu(cpu);
+ cpu->created = false;
+ qemu_cond_signal(&qemu_cpu_cond);
break;
}
}
-
- /* Pairs with smp_wmb in qemu_cpu_kick. */
- atomic_mb_set(&exit_request, 0);
}
static void *qemu_tcg_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
- CPUState *remove_cpu = NULL;
rcu_register_thread();
@@ -1195,8 +1174,41 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* process any pending work */
atomic_mb_set(&exit_request, 1);
+ cpu = first_cpu;
+
while (1) {
- tcg_exec_all();
+ /* Account partial waits to QEMU_CLOCK_VIRTUAL. */
+ qemu_account_warp_timer();
+
+ if (!cpu) {
+ cpu = first_cpu;
+ }
+
+ for (; cpu != NULL && !exit_request; cpu = CPU_NEXT(cpu)) {
+
+ qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
+ (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
+
+ if (cpu_can_run(cpu)) {
+ int r;
+ tcg_cpu_exec_start(cpu);
+ r = tcg_cpu_exec(cpu);
+ tcg_cpu_exec_end(cpu);
+ if (r == EXCP_DEBUG) {
+ cpu_handle_guest_debug(cpu);
+ break;
+ }
+ } else if (cpu->stop || cpu->stopped) {
+ if (cpu->unplug) {
+ cpu = CPU_NEXT(cpu);
+ }
+ break;
+ }
+
+ } /* for cpu.. */
+
+ /* Pairs with smp_wmb in qemu_cpu_kick. */
+ atomic_mb_set(&exit_request, 0);
if (use_icount) {
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
@@ -1206,18 +1218,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
}
qemu_tcg_wait_io_event(QTAILQ_FIRST(&cpus));
- CPU_FOREACH(cpu) {
- if (cpu->unplug && !cpu_can_run(cpu)) {
- remove_cpu = cpu;
- break;
- }
- }
- if (remove_cpu) {
- qemu_tcg_destroy_vcpu(remove_cpu);
- cpu->created = false;
- qemu_cond_signal(&qemu_cpu_cond);
- remove_cpu = NULL;
- }
+ deal_with_unplugged_cpus();
}
return NULL;
--
2.7.4
- [Qemu-devel] [RFC v4 03/28] translate-all: add DEBUG_LOCKING asserts, (continued)
- [Qemu-devel] [RFC v4 03/28] translate-all: add DEBUG_LOCKING asserts, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 05/28] docs: new design document multi-thread-tcg.txt (DRAFTING), Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 08/28] translate-all: Add assert_(memory|tb)_lock annotations, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 10/28] target-arm/arm-powerctl: wake up sleeping CPUs, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 07/28] linux-user/elfload: ensure mmap_lock() held while setting up, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 06/28] tcg: comment on which functions have to be called with tb_lock held, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 15/28] tcg: rename tcg_current_cpu to tcg_current_rr_cpu, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 09/28] tcg: protect TBContext with tb_lock., Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 11/28] tcg: move tcg_exec_all and helpers above thread fn, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 14/28] tcg: add kick timer for single-threaded vCPU emulation, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 12/28] tcg: cpus rm tcg_exec_all(),
Alex Bennée <=
- [Qemu-devel] [RFC v4 13/28] tcg: add options for enabling MTTCG, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 17/28] cpus: re-factor out handle_icount_deadline, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 18/28] tcg: remove global exit_request, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 19/28] tcg: move locking for tb_invalidate_phys_page_range up, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 16/28] tcg: drop global lock during TCG code execution, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 21/28] tcg: enable tb_lock() for SoftMMU, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 22/28] tcg: enable thread-per-vCPU, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 25/28] cputlb: introduce tlb_flush_* async work., Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 23/28] atomic: introduce cmpxchg_bool, Alex Bennée, 2016/08/11
- [Qemu-devel] [RFC v4 24/28] cputlb: add assert_cpu_is_self checks, Alex Bennée, 2016/08/11