]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: add energytune to domain XML
authorJedrzej Wasiukiewicz <jedrzej.wasiukiewicz@intel.com>
Thu, 14 May 2026 14:41:04 +0000 (16:41 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 15 May 2026 12:02:17 +0000 (14:02 +0200)
The new XML element is <energytune> under <cputune> following earlier pattern for
resctrl features (cachetune, memorytune). Energytune doesn't currently support
the "tuning" part, only monitoring. I added it as energytune for consistency with
cache and memory features, keeping all resctrl handling under cputune. This also makes
sense with current resctrl architecture - all monitoring groups are part of an
allocation group.

Changes:
 - Added <energytune> parsing to domain_conf.c
 - Added schema definition in domaincommon.rng
 - Documented the element in formatdomain.rst
 - Added energytune test

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>
docs/formatdomain.rst
src/conf/domain_conf.c
src/conf/schemas/domaincommon.rng
tests/genericxml2xmlindata/energytune.xml [new file with mode: 0644]
tests/genericxml2xmltest.c

index 078cd7aa84afafd5a8b61596308e325e29756388..db1ca5637a18d5321ea3ace7907bb8190f45e69a 100644 (file)
@@ -900,6 +900,9 @@ CPU Tuning
        <memorytune vcpus='0-3'>
          <node id='0' bandwidth='60'/>
        </memorytune>
+       <energytune vcpus='0-3'>
+         <monitor vcpus='0-3'/>
+       </energytune>
 
      </cputune>
      ...
@@ -1084,6 +1087,23 @@ CPU Tuning
          responsible for making sure the value makes sense on their system and
          configuration.
 
+``energytune`` :since:`Since 12.4.0`
+   Optional ``energytune`` element allows to monitor energy consumption using the
+   resctrl filesystem on the host. Whether or not is this supported can be
+   gathered from capabilities where number of monitors and available features are
+   reported. The required attribute ``vcpus`` specifies to which allocation group
+   this monitor belongs. A vCPU can only be member of one allocation group and monitor
+   group. The ``vcpus`` specified by ``energytune`` can be identical to those
+   specified by ``cachetune`` or ``memorytune``. However they are not allowed to
+   overlap each other. Supported subelements are:
+
+   ``monitor``
+      The optional element ``monitor`` creates the energy monitor for
+      this allocation group and has the following required attribute:
+
+      ``vcpus``
+         vCPU list the monitor applies to.
+
 
 Memory Allocation
 -----------------
index d73bac5cc5ad9c120b0cabfad9510832d330a84b..2d3e646bcb5e431f7ccf845b26d62d33ae1e10d4 100644 (file)
@@ -19467,6 +19467,57 @@ virDomainMemorytuneDefParse(virDomainDef *def,
 }
 
 
+static int
+virDomainEnergytuneDefParse(virDomainDef *def,
+                            xmlXPathContextPtr ctxt,
+                            xmlNodePtr node,
+                            unsigned int flags)
+{
+    VIR_XPATH_NODE_AUTORESTORE(ctxt)
+    virDomainResctrlDef *resctrl = NULL;
+    virDomainResctrlDef *newresctrl = NULL;
+    g_autoptr(virBitmap) vcpus = NULL;
+    g_autoptr(virResctrlAlloc) alloc = NULL;
+    size_t nmons;
+    int ret = -1;
+
+    ctxt->node = node;
+
+    if (virDomainResctrlParseVcpus(def, node, &vcpus) < 0)
+        return -1;
+
+    if (virBitmapIsAllClear(vcpus))
+        return 0;
+
+    if (virDomainResctrlVcpuMatch(def, vcpus, &resctrl) < 0)
+        return -1;
+
+    if (resctrl) {
+        alloc = virObjectRef(resctrl->alloc);
+    } else {
+        if (!(alloc = virResctrlAllocNew()))
+            return -1;
+        if (!(newresctrl = virDomainResctrlNew(node, alloc, vcpus, flags)))
+            return -1;
+        resctrl = newresctrl;
+    }
+
+    nmons = resctrl->nmonitors;
+    if (virDomainResctrlMonDefParse(def, ctxt, node,
+                                    VIR_RESCTRL_MONITOR_TYPE_ENERGY,
+                                    resctrl) < 0)
+        goto cleanup;
+
+    if (newresctrl && resctrl->nmonitors > nmons)
+        VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, newresctrl);
+
+    ret = 0;
+ cleanup:
+    virDomainResctrlDefFree(newresctrl);
+    return ret;
+}
+
+
 static int
 virDomainDefTunablesParse(virDomainDef *def,
                           xmlXPathContextPtr ctxt,
@@ -19671,6 +19722,15 @@ virDomainDefTunablesParse(virDomainDef *def,
     }
     VIR_FREE(nodes);
 
+    if ((n = virXPathNodeSet("./cputune/energytune", ctxt, &nodes)) < 0)
+        return -1;
+
+    for (i = 0; i < n; i++) {
+        if (virDomainEnergytuneDefParse(def, ctxt, nodes[i], flags) < 0)
+            return -1;
+    }
+    VIR_FREE(nodes);
+
     return 0;
 }
 
@@ -28721,6 +28781,42 @@ virDomainMemorytuneDefFormat(virBuffer *buf,
     return 0;
 }
 
+
+static int
+virDomainEnergytuneDefFormat(virBuffer *buf,
+                             virDomainResctrlDef *resctrl,
+                             unsigned int flags)
+{
+    g_auto(virBuffer) childrenBuf = VIR_BUFFER_INIT_CHILD(buf);
+    g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+    g_autofree char *vcpus = NULL;
+    size_t i;
+
+    for (i = 0; i < resctrl->nmonitors; i++) {
+        if (virDomainResctrlMonDefFormatHelper(resctrl->monitors[i],
+                                               VIR_RESCTRL_MONITOR_TYPE_ENERGY,
+                                               &childrenBuf) < 0)
+            return -1;
+    }
+
+    if (!virBufferUse(&childrenBuf))
+        return 0;
+
+    vcpus = virBitmapFormat(resctrl->vcpus);
+    virBufferAsprintf(&attrBuf, " vcpus='%s'", vcpus);
+
+    if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) {
+        const char *alloc_id = virResctrlAllocGetID(resctrl->alloc);
+        if (!alloc_id)
+            return -1;
+
+        virBufferAsprintf(&attrBuf, " id='%s'", alloc_id);
+    }
+
+    virXMLFormatElement(buf, "energytune", &attrBuf, &childrenBuf);
+    return 0;
+}
+
 static int
 virDomainCputuneDefFormat(virBuffer *buf,
                           virDomainDef *def,
@@ -28821,6 +28917,9 @@ virDomainCputuneDefFormat(virBuffer *buf,
     for (i = 0; i < def->nresctrls; i++)
         virDomainMemorytuneDefFormat(&childrenBuf, def->resctrls[i], flags);
 
+    for (i = 0; i < def->nresctrls; i++)
+        virDomainEnergytuneDefFormat(&childrenBuf, def->resctrls[i], flags);
+
     virXMLFormatElement(buf, "cputune", NULL, &childrenBuf);
 
     return 0;
index 8c03e14d374a97984f38560a6cc83559231c796f..eb365a83b573ad39ac60f0af8d1c3abeca4492e7 100644 (file)
             </oneOrMore>
           </element>
         </zeroOrMore>
+        <zeroOrMore>
+          <element name="energytune">
+            <attribute name="vcpus">
+              <ref name="cpuset"/>
+            </attribute>
+            <optional>
+              <attribute name="id">
+                <data type="string"/>
+              </attribute>
+            </optional>
+            <oneOrMore>
+              <element name="monitor">
+                <attribute name="vcpus">
+                  <ref name="cpuset"/>
+                </attribute>
+              </element>
+            </oneOrMore>
+          </element>
+        </zeroOrMore>
       </interleave>
     </element>
   </define>
diff --git a/tests/genericxml2xmlindata/energytune.xml b/tests/genericxml2xmlindata/energytune.xml
new file mode 100644 (file)
index 0000000..4ee4bed
--- /dev/null
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>4</vcpu>
+  <cputune>
+    <energytune vcpus='0-1'>
+      <monitor vcpus='0-1'/>
+    </energytune>
+    <energytune vcpus='3'>
+      <monitor vcpus='3'/>
+    </energytune>
+  </cputune>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-i386</emulator>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
index 6be694cac54de0e1dabb7d49531ecaabe5675a76..169c71efa39ea000af454e3ff31991f982b03adc 100644 (file)
@@ -210,6 +210,7 @@ mymain(void)
     DO_TEST("cachetune-small");
     DO_TEST("cachetune-cdp");
     DO_TEST("cachetune");
+    DO_TEST("energytune");
     DO_TEST_DIFFERENT("cachetune-extra-tunes");
     DO_TEST_FAIL_INACTIVE("cachetune-colliding-allocs");
     DO_TEST_FAIL_INACTIVE("cachetune-colliding-tunes");