qapi: introduce x-query-opcount QMP command
authorDaniel P. Berrangé <berrange@redhat.com>
Wed, 8 Sep 2021 09:35:43 +0000 (10:35 +0100)
committerDaniel P. Berrangé <berrange@redhat.com>
Tue, 2 Nov 2021 15:57:20 +0000 (15:57 +0000)
This is a counterpart to the HMP "info opcount" command. It is being
added with an "x-" prefix because this QMP command is intended as an
ad hoc debugging tool and will thus not be modelled in QAPI as fully
structured data, nor will it have long term guaranteed stability.
The existing HMP command is rewritten to call the QMP command.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
accel/tcg/cpu-exec.c
accel/tcg/hmp.c
accel/tcg/translate-all.c
include/exec/cpu-all.h
include/tcg/tcg.h
qapi/machine.json
tcg/tcg.c
tests/qtest/qmp-cmd-test.c

index 4212645cb6b13c6a26ccabc18f150f5a1d6aa7bb..c0620b4cc716886d18b0726e110881e7cb9f453e 100644 (file)
@@ -1066,4 +1066,18 @@ HumanReadableText *qmp_x_query_jit(Error **errp)
     return human_readable_text_from_str(buf);
 }
 
+HumanReadableText *qmp_x_query_opcount(Error **errp)
+{
+    g_autoptr(GString) buf = g_string_new("");
+
+    if (!tcg_enabled()) {
+        error_setg(errp, "Opcode count information is only available with accel=tcg");
+        return NULL;
+    }
+
+    dump_opcount_info(buf);
+
+    return human_readable_text_from_str(buf);
+}
+
 #endif /* !CONFIG_USER_ONLY */
index 01c767a4649cc092f164a28fd55fd5699ce0348a..d2ea35265538127f49c7248f39e291dc881bd599 100644 (file)
@@ -6,15 +6,10 @@
 #include "monitor/monitor.h"
 #include "sysemu/tcg.h"
 
-static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
-{
-    dump_opcount_info();
-}
-
 static void hmp_tcg_register(void)
 {
     monitor_register_hmp_info_hrt("jit", qmp_x_query_jit);
-    monitor_register_hmp("opcount", true, hmp_info_opcount);
+    monitor_register_hmp_info_hrt("opcount", qmp_x_query_opcount);
 }
 
 type_init(hmp_tcg_register);
index 8f17a9185882cbafc2d6b2144942c0e12fb48b3d..bd0bb81d0816abfcdfb8d286c48c6dc265add2da 100644 (file)
@@ -2118,9 +2118,9 @@ void dump_exec_info(GString *buf)
     tcg_dump_info(buf);
 }
 
-void dump_opcount_info(void)
+void dump_opcount_info(GString *buf)
 {
-    tcg_dump_op_count();
+    tcg_dump_op_count(buf);
 }
 
 #else /* CONFIG_USER_ONLY */
index d92f6fa7a973e023a6a30c5a1173bac3251af644..3c8e24292b599288ceb828c4d41c3cbd219f72bd 100644 (file)
@@ -432,7 +432,7 @@ static inline bool tlb_hit(target_ulong tlb_addr, target_ulong addr)
 void dump_drift_info(GString *buf);
 /* accel/tcg/translate-all.c */
 void dump_exec_info(GString *buf);
-void dump_opcount_info(void);
+void dump_opcount_info(GString *buf);
 #endif /* CONFIG_TCG */
 
 #endif /* !CONFIG_USER_ONLY */
index 7c8019a9b252b4ef937e6b91473e573e840276b5..42f5b500ed6a7692f6e2fbe448a241fe9316214d 100644 (file)
@@ -938,7 +938,7 @@ int tcg_check_temp_count(void);
 
 int64_t tcg_cpu_exec_time(void);
 void tcg_dump_info(GString *buf);
-void tcg_dump_op_count(void);
+void tcg_dump_op_count(GString *buf);
 
 #define TCG_CT_CONST  1 /* any constant of register size */
 
index 422a44661f610ef96466d92e32034eb152c030e3..17794ef6818e1c78bb77e26d48711cba4a51814f 100644 (file)
 { 'command': 'x-query-numa',
   'returns': 'HumanReadableText' }
 
+##
+# @x-query-opcount:
+#
+# Query TCG opcode counters
+#
+# Returns: TCG opcode counters
+#
+# Since: 6.2
+##
+{ 'command': 'x-query-opcount',
+  'returns': 'HumanReadableText',
+  'if': 'CONFIG_TCG' }
+
 ##
 # @x-query-profile:
 #
index f9ede8e62e90e0e7bbcfa49ad0a81cda0059f510..57f17a46496dc7b079c11f9ba43739a88861f09b 100644 (file)
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -4116,15 +4116,15 @@ static void tcg_profile_snapshot_table(TCGProfile *prof)
     tcg_profile_snapshot(prof, false, true);
 }
 
-void tcg_dump_op_count(void)
+void tcg_dump_op_count(GString *buf)
 {
     TCGProfile prof = {};
     int i;
 
     tcg_profile_snapshot_table(&prof);
     for (i = 0; i < NB_OPS; i++) {
-        qemu_printf("%s %" PRId64 "\n", tcg_op_defs[i].name,
-                    prof.table_op_count[i]);
+        g_string_append_printf(buf, "%s %" PRId64 "\n", tcg_op_defs[i].name,
+                               prof.table_op_count[i]);
     }
 }
 
@@ -4143,9 +4143,9 @@ int64_t tcg_cpu_exec_time(void)
     return ret;
 }
 #else
-void tcg_dump_op_count(void)
+void tcg_dump_op_count(GString *buf)
 {
-    qemu_printf("[TCG profiler not compiled]\n");
+    g_string_append_printf(buf, "[TCG profiler not compiled]\n");
 }
 
 int64_t tcg_cpu_exec_time(void)
index ea24fde1a3db7bf61baf0423a095efbae30ac4ca..7f103ea3fd2ac5c9fd0b6ebb91ce4b66bac31a41 100644 (file)
@@ -53,6 +53,7 @@ static int query_error_class(const char *cmd)
         { "x-query-usb", ERROR_CLASS_GENERIC_ERROR },
         /* Only valid with accel=tcg */
         { "x-query-jit", ERROR_CLASS_GENERIC_ERROR },
+        { "x-query-opcount", ERROR_CLASS_GENERIC_ERROR },
         { NULL, -1 }
     };
     int i;