]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: resctrl energy counters via domstats
authorJedrzej Wasiukiewicz <jedrzej.wasiukiewicz@intel.com>
Thu, 14 May 2026 14:41:05 +0000 (16:41 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 15 May 2026 12:02:20 +0000 (14:02 +0200)
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>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
include/libvirt/libvirt-domain.h
src/qemu/qemu_driver.c

index cf05bfe2b75781daaad82fd8bae76af7dee15678..1066a0b3f1438a6fa63a35b8a4f72e9033801937 100644 (file)
@@ -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:
  *
index a3d648e268727c01c4c5ad33f887c7f2349847b4..eda1f42054af7c6d00f303569d3a27c9bcc878c2 100644 (file)
@@ -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,63 @@ 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;
+
+    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++) {
+        size_t j = 0;
+
+        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;
+            size_t k = 0;
+
+            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 +17472,8 @@ qemuDomainGetStatsCpu(virQEMUDriver *driver,
 
     qemuDomainGetStatsCpuCache(driver, dom, params);
 
+    qemuDomainGetStatsEnergy(driver, dom, params);
+
     qemuDomainGetStatsCpuHaltPollTime(dom, params, privflags);
 }