aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio G. Cota <cota@braap.org>2018-10-10 10:48:53 -0400
committerRichard Henderson <richard.henderson@linaro.org>2018-10-18 18:58:10 -0700
commit72fd2efbbd52c1a7974000a60a0c2131b1a4aaf2 (patch)
tree888c2d7d7dfd9ba129d591d6891e002a521b987a
parentdd1d7da23b0abef87f46d9ab39ba9b0974eaec04 (diff)
tcg: distribute tcg_time into TCG contexts
When we implemented per-vCPU TCG contexts, we forgot to also distribute the tcg_time counter, which has remained as a global accessed without any serialization, leading to potentially missed counts. Fix it by distributing the field over the TCG contexts, embedding it into TCGProfile with a field called "cpu_exec_time", which is more descriptive than "tcg_time". Add a function to query this value directly, and for completeness, fill in the field in tcg_profile_snapshot, even though its callers do not use it. Signed-off-by: Emilio G. Cota <cota@braap.org> Message-Id: <20181010144853.13005-5-cota@braap.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--cpus.c3
-rw-r--r--include/qemu/timer.h1
-rw-r--r--monitor.c13
-rw-r--r--tcg/tcg.c23
-rw-r--r--tcg/tcg.h2
5 files changed, 37 insertions, 5 deletions
diff --git a/cpus.c b/cpus.c
index 361678e459..cce64874e6 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1425,7 +1425,8 @@ static int tcg_cpu_exec(CPUState *cpu)
ret = cpu_exec(cpu);
cpu_exec_end(cpu);
#ifdef CONFIG_PROFILER
- tcg_time += profile_getclock() - ti;
+ atomic_set(&tcg_ctx->prof.cpu_exec_time,
+ tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti);
#endif
return ret;
}
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index a005ed2692..dfecd03e28 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -1046,7 +1046,6 @@ static inline int64_t profile_getclock(void)
return get_clock();
}
-extern int64_t tcg_time;
extern int64_t dev_time;
#endif
diff --git a/monitor.c b/monitor.c
index b9258a7438..823b5a1099 100644
--- a/monitor.c
+++ b/monitor.c
@@ -83,6 +83,7 @@
#include "sysemu/cpus.h"
#include "sysemu/iothread.h"
#include "qemu/cutils.h"
+#include "tcg/tcg.h"
#if defined(TARGET_S390X)
#include "hw/s390x/storage-keys.h"
@@ -1966,16 +1967,22 @@ static void hmp_info_numa(Monitor *mon, const QDict *qdict)
#ifdef CONFIG_PROFILER
-int64_t tcg_time;
int64_t dev_time;
static void hmp_info_profile(Monitor *mon, const QDict *qdict)
{
+ static int64_t last_cpu_exec_time;
+ int64_t cpu_exec_time;
+ int64_t delta;
+
+ cpu_exec_time = tcg_cpu_exec_time();
+ delta = cpu_exec_time - last_cpu_exec_time;
+
monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
- tcg_time, tcg_time / (double)NANOSECONDS_PER_SECOND);
- tcg_time = 0;
+ delta, delta / (double)NANOSECONDS_PER_SECOND);
+ last_cpu_exec_time = cpu_exec_time;
dev_time = 0;
}
#else
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 8f26916b99..e85133ef05 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -30,6 +30,7 @@
/* Define to jump the ELF file used to communicate with GDB. */
#undef DEBUG_JIT
+#include "qemu/error-report.h"
#include "qemu/cutils.h"
#include "qemu/host-utils.h"
#include "qemu/timer.h"
@@ -3361,6 +3362,7 @@ void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
const TCGProfile *orig = &s->prof;
if (counters) {
+ PROF_ADD(prof, orig, cpu_exec_time);
PROF_ADD(prof, orig, tb_count1);
PROF_ADD(prof, orig, tb_count);
PROF_ADD(prof, orig, op_count);
@@ -3412,11 +3414,32 @@ void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
prof.table_op_count[i]);
}
}
+
+int64_t tcg_cpu_exec_time(void)
+{
+ unsigned int n_ctxs = atomic_read(&n_tcg_ctxs);
+ unsigned int i;
+ int64_t ret = 0;
+
+ for (i = 0; i < n_ctxs; i++) {
+ const TCGContext *s = atomic_read(&tcg_ctxs[i]);
+ const TCGProfile *prof = &s->prof;
+
+ ret += atomic_read(&prof->cpu_exec_time);
+ }
+ return ret;
+}
#else
void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
{
cpu_fprintf(f, "[TCG profiler not compiled]\n");
}
+
+int64_t tcg_cpu_exec_time(void)
+{
+ error_report("%s: TCG profiler not compiled", __func__);
+ exit(EXIT_FAILURE);
+}
#endif
diff --git a/tcg/tcg.h b/tcg/tcg.h
index d80ef2a883..c59f254e27 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -629,6 +629,7 @@ typedef struct TCGOp {
QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8));
typedef struct TCGProfile {
+ int64_t cpu_exec_time;
int64_t tb_count1;
int64_t tb_count;
int64_t op_count; /* total insn count */
@@ -1002,6 +1003,7 @@ int tcg_check_temp_count(void);
#define tcg_check_temp_count() 0
#endif
+int64_t tcg_cpu_exec_time(void);
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf);