Allow retrieving only a subset of statistics. This can be useful for example in order to plot a subset of the statistics many times a second.
KVM publishes ~40 statistics for each vCPU on x86; retrieving and serializing all of them would be useless Another use will be in HMP in the following patch; implementing the filter in the backend is easy enough that it was deemed okay to make this a public interface. Example: { "execute": "query-stats", "arguments": { "target": "vcpu", "vcpus": [ "/machine/unattached/device[2]", "/machine/unattached/device[4]" ], "providers": [ { "provider": "kvm", "names": [ "l1d_flush", "exits" ] } } } { "return": { "vcpus": [ { "path": "/machine/unattached/device[2]" "providers": [ { "provider": "kvm", "stats": [ { "name": "l1d_flush", "value": 41213 }, { "name": "exits", "value": 74291 } ] } ] }, { "path": "/machine/unattached/device[4]" "providers": [ { "provider": "kvm", "stats": [ { "name": "l1d_flush", "value": 16132 }, { "name": "exits", "value": 57922 } ] } ] } ] } } Extracted from a patch by Mark Kanda. Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- accel/kvm/kvm-all.c | 17 +++++++++++------ include/monitor/stats.h | 4 ++-- monitor/qmp-cmds.c | 10 +++++++--- qapi/stats.json | 6 +++++- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 12e003fdd2..403bc42ce0 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2311,7 +2311,7 @@ bool kvm_dirty_ring_enabled(void) return kvm_state->kvm_dirty_ring_size ? true : false; } -static void query_stats_cb(StatsResultList **result, StatsTarget target, +static void query_stats_cb(StatsResultList **result, StatsTarget target, strList *names, strList *targets, Error **errp); static void query_stats_schemas_cb(StatsSchemaList **result, Error **errp); @@ -3713,6 +3713,7 @@ typedef struct StatsArgs { StatsResultList **stats; StatsSchemaList **schema; } result; + strList *names; Error **errp; } StatsArgs; @@ -3926,7 +3927,7 @@ static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd return descriptors; } -static void query_stats(StatsResultList **result, StatsTarget target, +static void query_stats(StatsResultList **result, StatsTarget target, strList *names, int stats_fd, Error **errp) { struct kvm_stats_desc *kvm_stats_desc; @@ -3969,6 +3970,9 @@ static void query_stats(StatsResultList **result, StatsTarget target, /* Add entry to the list */ stats = (void *)stats_data + pdesc->offset; + if (!str_in_list(pdesc->name, names)) { + continue; + } stats_list = add_kvmstat_entry(pdesc, stats, stats_list, errp); } @@ -4030,8 +4034,8 @@ static void query_stats_vcpu(CPUState *cpu, run_on_cpu_data data) error_propagate(kvm_stats_args->errp, local_err); return; } - query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU, stats_fd, - kvm_stats_args->errp); + query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU, + kvm_stats_args->names, stats_fd, kvm_stats_args->errp); close(stats_fd); } @@ -4052,7 +4056,7 @@ static void query_stats_schema_vcpu(CPUState *cpu, run_on_cpu_data data) } static void query_stats_cb(StatsResultList **result, StatsTarget target, - strList *targets, Error **errp) + strList *names, strList *targets, Error **errp) { KVMState *s = kvm_state; CPUState *cpu; @@ -4066,7 +4070,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target, error_setg(errp, "KVM stats: ioctl failed"); return; } - query_stats(result, target, stats_fd, errp); + query_stats(result, target, names, stats_fd, errp); close(stats_fd); break; } @@ -4074,6 +4078,7 @@ static void query_stats_cb(StatsResultList **result, StatsTarget target, { StatsArgs stats_args; stats_args.result.stats = result; + stats_args.names = names; stats_args.errp = errp; CPU_FOREACH(cpu) { if (!str_in_list(cpu->parent_obj.canonical_path, targets)) { diff --git a/include/monitor/stats.h b/include/monitor/stats.h index acfd975df9..b4123044f7 100644 --- a/include/monitor/stats.h +++ b/include/monitor/stats.h @@ -11,8 +11,8 @@ #include "qapi/qapi-types-stats.h" typedef void StatRetrieveFunc(StatsResultList **result, StatsTarget target, - strList *targets, Error **errp); -typedef void SchemaRetrieveFunc(StatsSchemaList **result, Error **errp); + strList *names, strList *targets, Error **errp); +typedef void SchemaRetrieveFunc(StatsSchemaList **, Error **); /* * Register callbacks for the QMP query-stats command. diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 4d8a08879a..27b3d6ea74 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -483,15 +483,18 @@ static strList *stats_target_filter(StatsFilter *filter) } static bool stats_provider_requested(StatsProvider provider, - StatsFilter *filter) + StatsFilter *filter, + strList **p_names) { StatsRequestList *request; if (!filter->has_providers) { + *p_names = NULL; return true; } for (request = filter->providers; request; request = request->next) { if (request->value->provider == provider) { + *p_names = request->value->has_names ? request->value->names : NULL; return true; } } @@ -505,8 +508,9 @@ StatsResultList *qmp_query_stats(StatsFilter *filter, Error **errp) StatsCallbacks *entry; QTAILQ_FOREACH(entry, &stats_callbacks, next) { - if (stats_provider_requested(entry->provider, filter)) { - entry->stats_cb(&stats_results, filter->target, targets, errp); + strList *names = NULL; + if (stats_provider_requested(entry->provider, filter, &names)) { + entry->stats_cb(&stats_results, filter->target, names, targets, errp); } } diff --git a/qapi/stats.json b/qapi/stats.json index 712c48d001..fc763b4aea 100644 --- a/qapi/stats.json +++ b/qapi/stats.json @@ -74,11 +74,14 @@ # Indicates a set of statistics that should be returned by query-stats. # # @provider: provider for which to return statistics. + +# @names: statistics to be returned (all if omitted). # # Since: 7.1 ## { 'struct': 'StatsRequest', - 'data': { 'provider': 'StatsProvider' } } + 'data': { 'provider': 'StatsProvider', + '*names': [ 'str' ] } } ## # @StatsVCPUFilter: @@ -98,6 +101,7 @@ # that target: # - which vCPUs to request statistics for # - which provider to request statistics from +# - which values to return within each provider # # Since: 7.1 ## -- 2.36.0