On 5/14/26 16:41, Jedrzej Wasiukiewicz wrote:
Added energy reporting from resctrl PERF_PK_MON through domstats: cpu.energy.monitor.count=1 cpu.energy.monitor.0.name=vcpus_0 cpu.energy.monitor.0.vcpus=0 cpu.energy.monitor.0.pkg.count=2 cpu.energy.monitor.0.pkg.0.id=0 cpu.energy.monitor.0.pkg.0.core_energy=0.000000 cpu.energy.monitor.0.pkg.0.activity=0.000000 cpu.energy.monitor.0.pkg.1.id=1 cpu.energy.monitor.0.pkg.1.core_energy=2.888203 cpu.energy.monitor.0.pkg.1.activity=1.718601
Changes: - Added VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_* macros to libvirt-domain.h - Added qemuDomainGetStatsEnergy() to qemu_driver.c
Signed-off-by: Jedrzej Wasiukiewicz <jedrzej.wasiukiewicz@intel.com> Signed-off-by: Christopher M. Cantalupo <christopher.m.cantalupo@intel.com> --- include/libvirt/libvirt-domain.h | 65 +++++++++++++++++++++++++++++++ src/qemu/qemu_driver.c | 66 ++++++++++++++++++++++++++++++-- 2 files changed, 127 insertions(+), 4 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index cf05bfe2b7..1066a0b3f1 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4420,6 +4420,71 @@ struct _virDomainStatsRecord { # define VIR_DOMAIN_STATS_MEMORY_BANDWIDTH_MONITOR_SUFFIX_NODE_SUFFIX_BYTES_TOTAL ".bytes.total"
+/** + * VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_COUNT: + * + * The number of energy monitors for this domain, as an unsigned int. + * + * Since: 12.4.0 + */ +# define VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_COUNT "cpu.energy.monitor.count" + +/** + * VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_PREFIX: + * + * Prefix for an individual energy monitor group. Concatenate + * with the monitor index and one of the "cpu.energy.monitor.<i>." suffix + * macros below to form a full parameter name. + * + * Since: 12.4.0 + */ +# define VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_PREFIX "cpu.energy.monitor." + +/** + * VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_NAME: + * + * Name of the monitor group as a string. + * + * Since: 12.4.0 + */ +# define VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_NAME ".name" + +/** + * VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_VCPUS: + * + * vCPU set covered by the monitor group as a string. + * + * Since: 12.4.0 + */ +# define VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_VCPUS ".vcpus" + +/** + * VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_COUNT: + * + * Number of PERF_PKG nodes the monitor group exposes, as an unsigned int. + * + * Since: 12.4.0 + */ +# define VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_COUNT ".pkg.count" + +/** + * VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_PREFIX: + * + * Prefix for a single mon_PERF_PKG node inside a monitor group. + * + * Since: 12.4.0 + */ +# define VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_PREFIX ".pkg." + +/** + * VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_SUFFIX_ID: + * + * Kernel-assigned mon_PERF_PKG node id, as an unsigned int. + * + * Since: 12.4.0 + */ +# define VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_SUFFIX_ID ".id" + /** * VIR_DOMAIN_STATS_DIRTYRATE_CALC_STATUS: * diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a3d648e268..596e6ee7f3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17051,11 +17051,11 @@ qemuDomainFreeResctrlMonData(virQEMUResctrlMonData *resdata) * returns an error, the caller is also required to call * qemuDomainFreeResctrlMonData to free each element in the * *@resdata array and then the array itself. - * @tag: Could be VIR_RESCTRL_MONITOR_TYPE_CACHE for getting cache statistics - * from @dom cache monitors. VIR_RESCTRL_MONITOR_TYPE_MEMBW for - * getting memory bandwidth statistics from memory bandwidth monitors. + * @tag: VIR_RESCTRL_MONITOR_TYPE_CACHE for getting cache statistics. + * VIR_RESCTRL_MONITOR_TYPE_MEMBW for getting memory bandwidth statistics. + * VIR_RESCTRL_MONITOR_TYPE_ENERGY for getting energy statistics. * - * Get cache or memory bandwidth statistics from @dom monitors. + * Get cache, memory bandwidth or energy statistics from @dom monitors. * * Returns -1 on failure, or 0 on success. */ @@ -17204,6 +17204,62 @@ qemuDomainGetStatsMemoryBandwidth(virQEMUDriver *driver, }
+static void +qemuDomainGetStatsEnergy(virQEMUDriver *driver, + virDomainObj *dom, + virTypedParamList *params) +{ + g_autofree virQEMUResctrlMonData **resdata = NULL; + size_t nresdata = 0; + size_t i = 0; + size_t j = 0; + size_t k = 0;
We tend to declare variables in their smallest possible scope. IOW, these (j, and k) could be declared inside for() loops.
+ + if (!virDomainObjIsActive(dom)) + return; + + if (qemuDomainGetResctrlMonData(driver, dom, &resdata, &nresdata, + VIR_RESCTRL_MONITOR_TYPE_ENERGY) < 0) { + virResetLastError(); + return; + } + + if (nresdata == 0) + return; + + virTypedParamListAddUInt(params, nresdata, + VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_COUNT); + + for (i = 0; i < nresdata; i++) { + virTypedParamListAddString(params, resdata[i]->name, + VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_PREFIX "%zu" VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_NAME, i); + virTypedParamListAddString(params, resdata[i]->vcpus, + VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_PREFIX "%zu" VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_VCPUS, i); + virTypedParamListAddUInt(params, resdata[i]->nstats, + VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_PREFIX "%zu" VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_COUNT, i); + + for (j = 0; j < resdata[i]->nstats; j++) { + char **features = resdata[i]->stats[j]->features; + + virTypedParamListAddUInt(params, resdata[i]->stats[j]->id, + VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_PREFIX "%zu" VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_PREFIX "%zu" VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_SUFFIX_ID, i, j); + + for (k = 0; features[k]; k++) { + if (k >= resdata[i]->stats[j]->ndvals) + break; + + virTypedParamListAddDouble(params, resdata[i]->stats[j]->dvals[k], + VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_PREFIX "%zu" VIR_DOMAIN_STATS_CPU_ENERGY_MONITOR_SUFFIX_PKG_PREFIX "%zu" ".%s", i, j, + features[k]); + } + } + } + + for (i = 0; i < nresdata; i++) + qemuDomainFreeResctrlMonData(resdata[i]); +} + + static void qemuDomainGetStatsCpuCache(virQEMUDriver *driver, virDomainObj *dom, @@ -17415,6 +17471,8 @@ qemuDomainGetStatsCpu(virQEMUDriver *driver,
qemuDomainGetStatsCpuCache(driver, dom, params);
+ qemuDomainGetStatsEnergy(driver, dom, params); + qemuDomainGetStatsCpuHaltPollTime(dom, params, privflags); }
Michal