This is a counterpart to the HMP "info irq" command. It is being added with an "x-" prefix because this QMP command is intended as an adhoc 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.
This command is unable to use the pre-existing HumanReadableText, because if 'common.json' is included into 'machine-target.json' the static marshalling method for HumanReadableText will be reported as unused by the compiler on all architectures except s390x. Possible options were 1 Support 'if' conditionals on 'include' statements in QAPI 2 Add further commands to 'machine-target.json' that use HumanReadableText, such that it has at least one usage on all architecture targets. 3 Duplicate HumanReadableText as TargetHumanReadableText adding conditions This patch takes option (3) in the belief that we will eventually get to a point where option (2) happens, and TargetHumanReadableText can be removed again. Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> --- monitor/hmp-cmds.c | 40 ++++++++------------------------------- monitor/qmp-cmds.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ qapi/machine.json | 12 ++++++++++++ 3 files changed, 67 insertions(+), 32 deletions(-) diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 77533b2d8a..eb2202329d 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -784,42 +784,18 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev) } } -static int hmp_info_irq_foreach(Object *obj, void *opaque) +void hmp_info_irq(Monitor *mon, const QDict *qdict) { - InterruptStatsProvider *intc; - InterruptStatsProviderClass *k; - Monitor *mon = opaque; + Error *err = NULL; + g_autoptr(HumanReadableText) info = NULL; - 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) { - monitor_printf(mon, "IRQ statistics for %s:\n", - object_get_typename(obj)); - for (i = 0; i < nb_irqs; i++) { - if (irq_counts[i] > 0) { - monitor_printf(mon, "%2d: %" PRId64 "\n", i, - irq_counts[i]); - } - } - } - } else { - monitor_printf(mon, "IRQ statistics not available for %s.\n", - object_get_typename(obj)); - } + info = qmp_x_query_irq(&err); + if (err) { + error_report_err(err); + return; } - return 0; -} - -void hmp_info_irq(Monitor *mon, const QDict *qdict) -{ - object_child_foreach_recursive(object_get_root(), - hmp_info_irq_foreach, mon); + monitor_printf(mon, "%s", info->human_readable_text); } static int hmp_info_pic_foreach(Object *obj, void *opaque) diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index b86fff823e..cfb98658e4 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -40,6 +40,7 @@ #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) @@ -430,3 +431,49 @@ HumanReadableText *qmp_x_query_ramblock(Error **errp) ret->human_readable_text = g_steal_pointer(&buf->str); return ret; } + +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) +{ + HumanReadableText *ret; + g_autoptr(GString) buf = g_string_new(""); + + object_child_foreach_recursive(object_get_root(), + qmp_x_query_irq_foreach, buf); + + ret = g_new0(HumanReadableText, 1); + ret->human_readable_text = g_steal_pointer(&buf->str); + return ret; +} diff --git a/qapi/machine.json b/qapi/machine.json index 3ae7beb7cf..e72b47ea7d 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1313,6 +1313,18 @@ '*threads': 'int', '*maxcpus': 'int' } } +## +# @x-query-irq: +# +# Query interrupt statistics +# +# Returns: interrupt statistics +# +# Since: 6.2 +## +{ 'command': 'x-query-irq', + 'returns': 'HumanReadableText' } + ## # @x-query-numa: # -- 2.31.1