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 <[email protected]>
Signed-off-by: Christopher M. Cantalupo <[email protected]>
---
 docs/formatdomain.rst                     | 20 +++++
 src/conf/domain_conf.c                    | 99 +++++++++++++++++++++++
 src/conf/schemas/domaincommon.rng         | 19 +++++
 tests/genericxml2xmlindata/energytune.xml | 32 ++++++++
 tests/genericxml2xmltest.c                |  1 +
 5 files changed, 171 insertions(+)
 create mode 100644 tests/genericxml2xmlindata/energytune.xml

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 078cd7aa84..db1ca5637a 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -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
 -----------------
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d73bac5cc5..2d3e646bcb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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;
diff --git a/src/conf/schemas/domaincommon.rng 
b/src/conf/schemas/domaincommon.rng
index 8c03e14d37..eb365a83b5 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1293,6 +1293,25 @@
             </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
index 0000000000..4ee4bedb68
--- /dev/null
+++ b/tests/genericxml2xmlindata/energytune.xml
@@ -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>
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
index 6be694cac5..169c71efa3 100644
--- a/tests/genericxml2xmltest.c
+++ b/tests/genericxml2xmltest.c
@@ -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");
-- 
2.34.1

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial 
Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | 
Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z 
dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach 
handlowych.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i 
moze zawierac informacje poufne. W razie przypadkowego otrzymania tej 
wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; 
jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole 
use of the intended recipient(s). If you are not the intended recipient, please 
contact the sender and delete all copies; any review or distribution by others 
is strictly prohibited.

Reply via email to