summaryrefslogtreecommitdiffstats
path: root/monitor/qmp-cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'monitor/qmp-cmds.c')
-rw-r--r--monitor/qmp-cmds.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 5c0d5e116b..343353e27a 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -36,9 +36,13 @@
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-ui.h"
+#include "qapi/type-helpers.h"
#include "qapi/qmp/qerror.h"
+#include "exec/ramlist.h"
#include "hw/mem/memory-device.h"
#include "hw/acpi/acpi_dev_interface.h"
+#include "hw/intc/intc.h"
+#include "hw/rdma/rdma.h"
NameInfo *qmp_query_name(Error **errp)
{
@@ -350,3 +354,115 @@ void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
abort();
}
}
+
+#ifdef CONFIG_PROFILER
+
+int64_t dev_time;
+
+HumanReadableText *qmp_x_query_profile(Error **errp)
+{
+ g_autoptr(GString) buf = g_string_new("");
+ 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;
+
+ g_string_append_printf(buf, "async time %" PRId64 " (%0.3f)\n",
+ dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
+ g_string_append_printf(buf, "qemu time %" PRId64 " (%0.3f)\n",
+ delta, delta / (double)NANOSECONDS_PER_SECOND);
+ last_cpu_exec_time = cpu_exec_time;
+ dev_time = 0;
+
+ return human_readable_text_from_str(buf);
+}
+#else
+HumanReadableText *qmp_x_query_profile(Error **errp)
+{
+ error_setg(errp, "Internal profiler not compiled");
+ return NULL;
+}
+#endif
+
+static int qmp_x_query_rdma_foreach(Object *obj, void *opaque)
+{
+ RdmaProvider *rdma;
+ RdmaProviderClass *k;
+ GString *buf = opaque;
+
+ if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) {
+ rdma = RDMA_PROVIDER(obj);
+ k = RDMA_PROVIDER_GET_CLASS(obj);
+ if (k->format_statistics) {
+ k->format_statistics(rdma, buf);
+ } else {
+ g_string_append_printf(buf,
+ "RDMA statistics not available for %s.\n",
+ object_get_typename(obj));
+ }
+ }
+
+ return 0;
+}
+
+HumanReadableText *qmp_x_query_rdma(Error **errp)
+{
+ g_autoptr(GString) buf = g_string_new("");
+
+ object_child_foreach_recursive(object_get_root(),
+ qmp_x_query_rdma_foreach, buf);
+
+ return human_readable_text_from_str(buf);
+}
+
+HumanReadableText *qmp_x_query_ramblock(Error **errp)
+{
+ g_autoptr(GString) buf = ram_block_format();
+
+ return human_readable_text_from_str(buf);
+}
+
+static int qmp_x_query_irq_foreach(Object *obj, void *opaque)
+{
+ InterruptStatsProvider *intc;
+ InterruptStatsProviderClass *k;
+ GString *buf = opaque;
+
+ if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
+ intc = INTERRUPT_STATS_PROVIDER(obj);
+ k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
+ uint64_t *irq_counts;
+ unsigned int nb_irqs, i;
+ if (k->get_statistics &&
+ k->get_statistics(intc, &irq_counts, &nb_irqs)) {
+ if (nb_irqs > 0) {
+ g_string_append_printf(buf, "IRQ statistics for %s:\n",
+ object_get_typename(obj));
+ for (i = 0; i < nb_irqs; i++) {
+ if (irq_counts[i] > 0) {
+ g_string_append_printf(buf, "%2d: %" PRId64 "\n", i,
+ irq_counts[i]);
+ }
+ }
+ }
+ } else {
+ g_string_append_printf(buf,
+ "IRQ statistics not available for %s.\n",
+ object_get_typename(obj));
+ }
+ }
+
+ return 0;
+}
+
+HumanReadableText *qmp_x_query_irq(Error **errp)
+{
+ g_autoptr(GString) buf = g_string_new("");
+
+ object_child_foreach_recursive(object_get_root(),
+ qmp_x_query_irq_foreach, buf);
+
+ return human_readable_text_from_str(buf);
+}