Leverage the QMP support for fd-based KVM stats. The interface supports an optional 'filter' argument to specify a particular stat to query. Base and exponent are displayed in human readable format.
Examples: (qemu) info kvmstats vm: max_mmu_page_hash_collisions (peak): 0 nx_lpage_splits (instant): 114 lpages (instant): 193 mmu_unsync (instant): 0 mmu_cache_miss (cumulative): 293 mmu_recycled (cumulative): 0 mmu_flooded (cumulative): 0 mmu_pde_zapped (cumulative): 0 mmu_pte_write (cumulative): 0 mmu_shadow_zapped (cumulative): 178 remote_tlb_flush (cumulative): 63 vcpu_0: req_event (cumulative): 538 nmi_injections (cumulative): 0 ... (qemu) info kvmstats halt_poll_fail_ns vm: vcpu_0: halt_poll_fail_ns (cumulative): 20*10^-9 seconds vcpu_1: halt_poll_fail_ns (cumulative): 30*10^-9 seconds Signed-off-by: Mark Kanda <mark.ka...@oracle.com> --- hmp-commands-info.hx | 13 +++++++++++ include/monitor/hmp.h | 1 + monitor/hmp-cmds.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 4c966e8a6b..ef5bca01d9 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -335,6 +335,19 @@ SRST Show KVM information. ERST + { + .name = "kvmstats", + .args_type = "filter:s?", + .params = "filter", + .help = "show KVM statistics; optional filter for stat name", + .cmd = hmp_info_kvmstats, + }, + +SRST + ``info kvmstats`` + Show KVM statistics. +ERST + { .name = "numa", .args_type = "", diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 6bc27639e0..20be8f8586 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -21,6 +21,7 @@ void hmp_handle_error(Monitor *mon, Error *err); void hmp_info_name(Monitor *mon, const QDict *qdict); void hmp_info_version(Monitor *mon, const QDict *qdict); void hmp_info_kvm(Monitor *mon, const QDict *qdict); +void hmp_info_kvmstats(Monitor *mon, const QDict *qdict); void hmp_info_status(Monitor *mon, const QDict *qdict); void hmp_info_uuid(Monitor *mon, const QDict *qdict); void hmp_info_chardev(Monitor *mon, const QDict *qdict); diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index bcaa41350e..24a545a66b 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -134,6 +134,58 @@ void hmp_info_kvm(Monitor *mon, const QDict *qdict) qapi_free_KvmInfo(info); } +void hmp_info_kvmstats(Monitor *mon, const QDict *qdict) +{ + KvmStatsList *stats_list, *stats_list_entry; + KvmStats *stats_entry; + KvmStatDataList *data_entry; + KvmStatData *kvm_stat; + uint64List *val; + const char *filter; + Error *err = NULL; + + filter = qdict_get_try_str(qdict, "filter"); + if (filter) { + stats_list = qmp_query_kvmstats(TRUE, filter, &err); + } else { + stats_list = qmp_query_kvmstats(FALSE, NULL, &err); + } + + if (err) { + monitor_printf(mon, "%s\n", error_get_pretty(err)); + error_free(err); + return; + } + + for (stats_list_entry = stats_list; stats_list_entry; + stats_list_entry = stats_list_entry->next) { + stats_entry = stats_list_entry->value; + monitor_printf(mon, "\n%s:\n", stats_entry->name); + + for (data_entry = stats_entry->stats; data_entry; + data_entry = data_entry->next) { + kvm_stat = data_entry->value; + monitor_printf(mon, " %s (%s):", kvm_stat->name, + KvmStatType_str(kvm_stat->type)); + + for (val = kvm_stat->val; val; val = val->next) { + if (kvm_stat->exponent) { + /* Print the base and exponent as "*<base>^<exp>" */ + monitor_printf(mon, " %lu*%d^%d", val->value, + kvm_stat->base, kvm_stat->exponent); + } else { + monitor_printf(mon, " %lu", val->value); + } + } + + /* Don't print "none" unit type */ + monitor_printf(mon, " %s\n", kvm_stat->unit == KVM_STAT_UNIT_NONE ? + "" : KvmStatUnit_str(kvm_stat->unit)); + } + } + qapi_free_KvmStatsList(stats_list); +} + void hmp_info_status(Monitor *mon, const QDict *qdict) { StatusInfo *info; -- 2.26.2