aboutsummaryrefslogtreecommitdiff
path: root/accel
diff options
context:
space:
mode:
authorClaudio Fontana <cfontana@suse.de>2020-08-19 13:17:19 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2020-10-05 16:41:22 +0200
commit740b175973427bcfa32ad894bb1f83b96d184c28 (patch)
tree3613e83be5fd8620b369479b98e6ede5d5746a9a /accel
parent0ac0b47c44b4be6cbce26777a1a5968cc8f025a5 (diff)
cpu-timers, icount: new modules
refactoring of cpus.c continues with cpu timer state extraction. cpu-timers: responsible for the softmmu cpu timers state, including cpu clocks and ticks. icount: counts the TCG instructions executed. As such it is specific to the TCG accelerator. Therefore, it is built only under CONFIG_TCG. One complication is due to qtest, which uses an icount field to warp time as part of qtest (qtest_clock_warp). In order to solve this problem, provide a separate counter for qtest. This requires fixing assumptions scattered in the code that qtest_enabled() implies icount_enabled(), checking each specific case. Signed-off-by: Claudio Fontana <cfontana@suse.de> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> [remove redundant initialization with qemu_spice_init] Reviewed-by: Alex Bennée <alex.bennee@linaro.org> [fix lingering calls to icount_get] Signed-off-by: Claudio Fontana <cfontana@suse.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'accel')
-rw-r--r--accel/qtest.c6
-rw-r--r--accel/tcg/cpu-exec.c39
-rw-r--r--accel/tcg/tcg-all.c7
-rw-r--r--accel/tcg/translate-all.c3
4 files changed, 41 insertions, 14 deletions
diff --git a/accel/qtest.c b/accel/qtest.c
index 5b88f55921..119d0f16a4 100644
--- a/accel/qtest.c
+++ b/accel/qtest.c
@@ -19,14 +19,10 @@
#include "sysemu/accel.h"
#include "sysemu/qtest.h"
#include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
static int qtest_init_accel(MachineState *ms)
{
- QemuOpts *opts = qemu_opts_create(qemu_find_opts("icount"), NULL, 0,
- &error_abort);
- qemu_opt_set(opts, "shift", "0", &error_abort);
- configure_icount(opts, &error_abort);
- qemu_opts_del(opts);
return 0;
}
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index e10b46283c..35bfe2ca92 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
+#include "qemu/qemu-print.h"
#include "cpu.h"
#include "trace.h"
#include "disas/disas.h"
@@ -36,6 +37,8 @@
#include "hw/i386/apic.h"
#endif
#include "sysemu/cpus.h"
+#include "exec/cpu-all.h"
+#include "sysemu/cpu-timers.h"
#include "sysemu/replay.h"
/* -icount align implementation. */
@@ -56,6 +59,9 @@ typedef struct SyncClocks {
#define MAX_DELAY_PRINT_RATE 2000000000LL
#define MAX_NB_PRINTS 100
+static int64_t max_delay;
+static int64_t max_advance;
+
static void align_clocks(SyncClocks *sc, CPUState *cpu)
{
int64_t cpu_icount;
@@ -98,9 +104,9 @@ static void print_delay(const SyncClocks *sc)
(-sc->diff_clk / (float)1000000000LL <
(threshold_delay - THRESHOLD_REDUCE))) {
threshold_delay = (-sc->diff_clk / 1000000000LL) + 1;
- printf("Warning: The guest is now late by %.1f to %.1f seconds\n",
- threshold_delay - 1,
- threshold_delay);
+ qemu_printf("Warning: The guest is now late by %.1f to %.1f seconds\n",
+ threshold_delay - 1,
+ threshold_delay);
nb_prints++;
last_realtime_clock = sc->realtime_clock;
}
@@ -615,7 +621,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
/* Finally, check if we need to exit to the main loop. */
if (unlikely(qatomic_read(&cpu->exit_request))
- || (use_icount
+ || (icount_enabled()
&& cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra == 0)) {
qatomic_set(&cpu->exit_request, 0);
if (cpu->exception_index == -1) {
@@ -656,7 +662,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
}
/* Instruction counter expired. */
- assert(use_icount);
+ assert(icount_enabled());
#ifndef CONFIG_USER_ONLY
/* Ensure global icount has gone forward */
cpu_update_icount(cpu);
@@ -759,3 +765,26 @@ int cpu_exec(CPUState *cpu)
return ret;
}
+
+#ifndef CONFIG_USER_ONLY
+
+void dump_drift_info(void)
+{
+ if (!icount_enabled()) {
+ return;
+ }
+
+ qemu_printf("Host - Guest clock %"PRIi64" ms\n",
+ (cpu_get_clock() - cpu_get_icount()) / SCALE_MS);
+ if (icount_align_option) {
+ qemu_printf("Max guest delay %"PRIi64" ms\n",
+ -max_delay / SCALE_MS);
+ qemu_printf("Max guest advance %"PRIi64" ms\n",
+ max_advance / SCALE_MS);
+ } else {
+ qemu_printf("Max guest delay NA\n");
+ qemu_printf("Max guest advance NA\n");
+ }
+}
+
+#endif /* !CONFIG_USER_ONLY */
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 1c664924d7..2d13df3f72 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -29,6 +29,7 @@
#include "qom/object.h"
#include "cpu.h"
#include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
#include "qemu/main-loop.h"
#include "tcg/tcg.h"
#include "qapi/error.h"
@@ -66,7 +67,7 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask)
qemu_cpu_kick(cpu);
} else {
qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1);
- if (use_icount &&
+ if (icount_enabled() &&
!cpu->can_do_io
&& (mask & ~old_mask) != 0) {
cpu_abort(cpu, "Raised interrupt while not in I/O function");
@@ -105,7 +106,7 @@ static bool check_tcg_memory_orders_compatible(void)
static bool default_mttcg_enabled(void)
{
- if (use_icount || TCG_OVERSIZED_GUEST) {
+ if (icount_enabled() || TCG_OVERSIZED_GUEST) {
return false;
} else {
#ifdef TARGET_SUPPORTS_MTTCG
@@ -147,7 +148,7 @@ static void tcg_set_thread(Object *obj, const char *value, Error **errp)
if (strcmp(value, "multi") == 0) {
if (TCG_OVERSIZED_GUEST) {
error_setg(errp, "No MTTCG when guest word size > hosts");
- } else if (use_icount) {
+ } else if (icount_enabled()) {
error_setg(errp, "No MTTCG when icount is enabled");
} else {
#ifndef TARGET_SUPPORTS_MTTCG
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index e82fc35b32..d76097296d 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -57,6 +57,7 @@
#include "qemu/main-loop.h"
#include "exec/log.h"
#include "sysemu/cpus.h"
+#include "sysemu/cpu-timers.h"
#include "sysemu/tcg.h"
/* #define DEBUG_TB_INVALIDATE */
@@ -369,7 +370,7 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
found:
if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) {
- assert(use_icount);
+ assert(icount_enabled());
/* Reset the cycle counter to the start of the block
and shift if to the number of actually executed instructions */
cpu_neg(cpu)->icount_decr.u16.low += num_insns - i;