]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: report energy monitoring in host capabilities
authorJedrzej Wasiukiewicz <jedrzej.wasiukiewicz@intel.com>
Thu, 14 May 2026 14:41:03 +0000 (16:41 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 15 May 2026 12:02:14 +0000 (14:02 +0200)
Expose PERF_PKG_MON energy monitoring capabilities in the host
capabilities XML.
<energy>
  <monitor maxMonitors='576'>
    <feature name='core_energy'/>
    <feature name='activity'/>
  </monitor>
</energy>

Changes:
 - Add virCapabilitiesFormatEnergy() to emit <energy> XML block
 - Add virCapabilitiesInitEnergy() to init from PERF_PKG_MON info
 - Add <energy> element and energyMonitorFeature to capability.rng
 - Update qemu_driver to support VIR_RESCTRL_MONITOR_TYPE_ENERGY
 - Add virCapsHostEnergy struct

Signed-off-by: Jedrzej Wasiukiewicz <jedrzej.wasiukiewicz@intel.com>
Signed-off-by: Christopher M. Cantalupo <christopher.m.cantalupo@intel.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/conf/capabilities.c
src/conf/capabilities.h
src/conf/schemas/capability.rng
src/conf/virconftypes.h
src/qemu/qemu_driver.c

index 1821e36e610aa3ead7f4f2f5b28f60187f79c939..e83de6d1bcfe8db0a49bc25177b1266b9bf583f3 100644 (file)
@@ -263,6 +263,8 @@ virCapsDispose(void *object)
     virResctrlInfoMonFree(caps->host.memBW.monitor);
     g_free(caps->host.memBW.nodes);
 
+    virResctrlInfoMonFree(caps->host.energy.monitor);
+
     g_free(caps->host.netprefix);
     g_free(caps->host.pagesSize);
     virCPUDefFree(caps->host.cpu);
@@ -1057,6 +1059,26 @@ virCapabilitiesFormatMemoryBandwidth(virBuffer *buf,
 }
 
 
+static int
+virCapabilitiesFormatEnergy(virBuffer *buf,
+                            virCapsHostEnergy *energy)
+{
+    if (!energy->monitor)
+        return 0;
+
+    virBufferAddLit(buf, "<energy>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    if (virCapabilitiesFormatResctrlMonitor(buf, energy->monitor) < 0)
+        return -1;
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</energy>\n");
+
+    return 0;
+}
+
+
 static int
 virCapabilitiesFormatHostXML(virCapsHost *host,
                              virBuffer *buf)
@@ -1156,6 +1178,9 @@ virCapabilitiesFormatHostXML(virCapsHost *host,
     if (virCapabilitiesFormatMemoryBandwidth(buf, &host->memBW) < 0)
         return -1;
 
+    if (virCapabilitiesFormatEnergy(buf, &host->energy) < 0)
+        return -1;
+
     for (i = 0; i < host->nsecModels; i++) {
         virBufferAddLit(buf, "<secmodel>\n");
         virBufferAdjustIndent(buf, 2);
@@ -2143,6 +2168,20 @@ virCapabilitiesInitResctrlMemory(virCaps *caps)
 }
 
 
+static int
+virCapabilitiesInitEnergy(virCaps *caps)
+{
+    const char *prefix = virResctrlMonitorPrefixTypeToString(
+        VIR_RESCTRL_MONITOR_TYPE_ENERGY);
+
+    if (virResctrlInfoGetMonitorPrefix(caps->host.resctrl, prefix,
+                                       &caps->host.energy.monitor) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 int
 virCapabilitiesInitCaches(virCaps *caps)
 {
@@ -2294,6 +2333,9 @@ virCapabilitiesInitCaches(virCaps *caps)
                                        &caps->host.cache.monitor) < 0)
         return -1;
 
+    if (virCapabilitiesInitEnergy(caps) < 0)
+        return -1;
+
     return 0;
 }
 
index daea835817ab722177c69c4df35352ac0f4d314d..0482e4297a28e23b02903ec0819c5a97a5a1bf82 100644 (file)
@@ -162,6 +162,10 @@ struct _virCapsHostMemBW {
     virResctrlInfoMon *monitor;
 };
 
+struct _virCapsHostEnergy {
+    virResctrlInfoMon *monitor;
+};
+
 struct _virCapsHost {
     virArch arch;
     size_t nfeatures;
@@ -184,6 +188,8 @@ struct _virCapsHost {
 
     virCapsHostMemBW memBW;
 
+    virCapsHostEnergy energy;
+
     size_t nsecModels;
     virCapsHostSecModel *secModels;
 
index 8ef6e9a2824fe94ee44344c77fcb70a12e0fe93a..6160067dc7810e277f88b76653a9ca5ea8289867 100644 (file)
@@ -45,6 +45,9 @@
       <optional>
         <ref name="memory_bandwidth"/>
       </optional>
+      <optional>
+        <ref name="energy"/>
+      </optional>
       <zeroOrMore>
         <ref name="secmodel"/>
       </zeroOrMore>
     </data>
   </define>
 
+  <define name="energyMonitorFeature">
+    <choice>
+      <value>core_energy</value>
+      <value>activity</value>
+    </choice>
+  </define>
+
+  <define name="energy">
+    <element name="energy">
+      <element name="monitor">
+        <attribute name="maxMonitors">
+          <ref name="unsignedInt"/>
+        </attribute>
+        <oneOrMore>
+          <element name="feature">
+            <attribute name="name">
+              <ref name="energyMonitorFeature"/>
+            </attribute>
+          </element>
+        </oneOrMore>
+      </element>
+    </element>
+  </define>
+
   <define name="guestcaps">
     <element name="guest">
       <ref name="ostype"/>
index 0596791a4dae71efefe8944e2b92b8105d9a8b87..f1a200bfe24865db97f821ca3e5c034ca7dc6e30 100644 (file)
@@ -52,6 +52,8 @@ typedef struct _virCapsHostMemBW virCapsHostMemBW;
 
 typedef struct _virCapsHostMemBWNode virCapsHostMemBWNode;
 
+typedef struct _virCapsHostEnergy virCapsHostEnergy;
+
 typedef struct _virCapsHostNUMA virCapsHostNUMA;
 
 typedef struct _virCapsHostNUMACell virCapsHostNUMACell;
index 2d509cd2b91689830882798d4789f840f7f47743..a3d648e268727c01c4c5ad33f887c7f2349847b4 100644 (file)
@@ -17086,6 +17086,9 @@ qemuDomainGetResctrlMonData(virQEMUDriver *driver,
             features = caps->host.memBW.monitor->features;
         break;
     case VIR_RESCTRL_MONITOR_TYPE_ENERGY:
+        if (caps->host.energy.monitor)
+            features = caps->host.energy.monitor->features;
+        break;
     case VIR_RESCTRL_MONITOR_TYPE_UNSUPPORT:
     case VIR_RESCTRL_MONITOR_TYPE_LAST:
         virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",