From: "Vanderson M. do Rosario" <vanderson...@gmail.com> Add tb_stats [start|stop|status] command to hmp. This allows controlling the collection of statistics.
The goal of this command is to allow the dynamic exploration of the TCG behavior and quality. Therefore, for now, a corresponding QMP command is not considered worthwhile. Acked-by: Dr. David Alan Gilbert <dgilb...@redhat.com> Signed-off-by: Vanderson M. do Rosario <vanderson...@gmail.com> Signed-off-by: Alex Bennée <alex.ben...@linaro.org> Signed-off-by: Fei Wu <fei2...@intel.com> [rth: Significantly reorganized.] Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- accel/tcg/monitor.c | 70 ++++++++++++++++++++++++++++++++++++++++++++- hmp-commands.hx | 15 ++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c index 093efe9714..370fea883c 100644 --- a/accel/tcg/monitor.c +++ b/accel/tcg/monitor.c @@ -12,11 +12,15 @@ #include "qapi/error.h" #include "qapi/type-helpers.h" #include "qapi/qapi-commands-machine.h" +#include "qapi/qmp/qdict.h" #include "monitor/monitor.h" +#include "monitor/hmp.h" #include "sysemu/cpus.h" #include "sysemu/cpu-timers.h" #include "sysemu/tcg.h" #include "tcg/tcg.h" +#include "tcg/tb-stats.h" +#include "exec/tb-flush.h" #include "internal-common.h" #include "tb-context.h" @@ -235,10 +239,74 @@ HumanReadableText *qmp_x_query_opcount(Error **errp) return human_readable_text_from_str(buf); } +static void tb_stats_init_safe(CPUState *cpu, run_on_cpu_data icmd) +{ + uint32_t flags = icmd.host_int; + + tb_stats_init(flags); + tb_flush(cpu); +} + +static void hmp_tbstats(Monitor *mon, const QDict *qdict) +{ + uint32_t flags = TB_STATS_NONE; + const char *cmd; + + if (!tcg_enabled()) { + monitor_printf(mon, "Only available with accel=tcg\n"); + return; + } + + cmd = qdict_get_try_str(qdict, "command"); + + if (strcmp(cmd, "start") == 0) { + const char *sflag = qdict_get_try_str(qdict, "flag"); + + flags = TB_STATS_ALL; + if (sflag) { + if (strcmp(sflag, "all") == 0) { + flags = TB_STATS_ALL; + } else if (strcmp(sflag, "jit") == 0) { + flags = TB_STATS_JIT; + } else if (strcmp(sflag, "exec") == 0) { + flags = TB_STATS_EXEC; + } else { + monitor_printf(mon, "Invalid argument to tb_stats start\n"); + return; + } + } + + if (tb_stats_enabled) { + monitor_printf(mon, "TB statistics already being recorded\n"); + return; + } + } else if (strcmp(cmd, "stop") == 0) { + if (!tb_stats_enabled) { + monitor_printf(mon, "TB statistics not being recorded\n"); + return; + } + } else if (strcmp(cmd, "status") == 0) { + if (tb_stats_enabled) { + monitor_printf(mon, "TB statistics are enabled:%s%s\n", + tb_stats_enabled & TB_STATS_EXEC ? " EXEC" : "", + tb_stats_enabled & TB_STATS_JIT ? " JIT" : ""); + } else { + monitor_printf(mon, "TB statistics are disabled\n"); + } + return; + } else { + monitor_printf(mon, "Invalid command\n"); + return; + } + + async_safe_run_on_cpu(first_cpu, tb_stats_init_safe, + RUN_ON_CPU_HOST_INT(flags)); +} + static void hmp_tcg_register(void) { monitor_register_hmp_info_hrt("jit", qmp_x_query_jit); monitor_register_hmp_info_hrt("opcount", qmp_x_query_opcount); + monitor_register_hmp("tb_stats", false, hmp_tbstats); } - type_init(hmp_tcg_register); diff --git a/hmp-commands.hx b/hmp-commands.hx index 63eac22734..e1d78ab69d 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1673,6 +1673,21 @@ SRST Executes a qemu-io command on the given block device. ERST +#if defined(CONFIG_TCG) + { + .name = "tb_stats", + .args_type = "command:s,flag:s?", + .params = "command [flag]", + .help = "Control tb statistics collection:" + "tb_stats (start|stop|status) [all|jit|exec]", + }, +#endif + +SRST +``tb_stats`` *command* *flag* + Control recording tb statistics +ERST + { .name = "qom-list", .args_type = "path:s?", -- 2.34.1