From: Huaqiang <huaqiang.wang(a)intel.com>
Create memory bandwidth monitor.
Following domain configuration changes create two memory bandwidth
monitors: one is monitoring the bandwidth consumed by vCPU 0,
another is for vCPU 5.
```
<cputune>
<memorytune vcpus='0-4'>
<node id='0' bandwidth='20'/>
<node id='1' bandwidth='30'/>
+ <monitor vcpus='0'/>
</memorytune>
+ <memorytune vcpus='5'>
+ <monitor vcpus='5'/>
+ </memorytune>
</cputune>
```
Signed-off-by: Huaqiang <huaqiang.wang(a)intel.com>
---
docs/schemas/domaincommon.rng | 23 +++++++----
src/conf/domain_conf.c | 44 +++++++++++++++++-----
tests/genericxml2xmlindata/memorytune.xml | 5 +++
tests/genericxml2xmloutdata/memorytune.xml | 42 +++++++++++++++++++++
tests/genericxml2xmltest.c | 2 +-
5 files changed, 98 insertions(+), 18 deletions(-)
create mode 100644 tests/genericxml2xmloutdata/memorytune.xml
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index aa4f512e5c..adf1fcb36d 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1023,14 +1023,21 @@
<ref name='cpuset'/>
</attribute>
<oneOrMore>
- <element name="node">
- <attribute name="id">
- <ref name='unsignedInt'/>
- </attribute>
- <attribute name="bandwidth">
- <ref name='unsignedInt'/>
- </attribute>
- </element>
+ <choice>
+ <element name="node">
+ <attribute name="id">
+ <ref name='unsignedInt'/>
+ </attribute>
+ <attribute name="bandwidth">
+ <ref name='unsignedInt'/>
+ </attribute>
+ </element>
+ <element name="monitor">
+ <attribute name="vcpus">
+ <ref name='cpuset'/>
+ </attribute>
+ </element>
+ </choice>
</oneOrMore>
</element>
</zeroOrMore>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 875490dd2b..51bf18a42b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19639,10 +19639,14 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
{
VIR_XPATH_NODE_AUTORESTORE(ctxt);
virDomainResctrlDefPtr resctrl = NULL;
+ virDomainResctrlDefPtr newresctrl = NULL;
g_autoptr(virBitmap) vcpus = NULL;
g_autofree xmlNodePtr *nodes = NULL;
g_autoptr(virResctrlAlloc) alloc = NULL;
ssize_t i = 0;
+ size_t nmons = 0;
+ size_t ret = -1;
+
int n;
ctxt->node = node;
@@ -19669,29 +19673,44 @@ virDomainMemorytuneDefParse(virDomainDefPtr def,
return -1;
}
+ /* First, parse <memorytune/node> element if any <node> element exists
*/
for (i = 0; i < n; i++) {
if (virDomainMemorytuneDefParseMemory(ctxt, nodes[i], alloc) < 0)
return -1;
}
- if (n == 0)
- return 0;
-
/*
* If this is a new allocation, format ID and append to resctrl, otherwise
* just update the existing alloc information, which is done in above
* virDomainMemorytuneDefParseMemory */
if (!resctrl) {
- if (!(resctrl = virDomainResctrlNew(node, alloc, vcpus, flags)))
+ if (!(newresctrl = virDomainResctrlNew(node, alloc, vcpus, flags)))
return -1;
- if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, resctrl) < 0) {
- virDomainResctrlDefFree(resctrl);
- return -1;
- }
+ resctrl = newresctrl;
}
- return 0;
+ /* Next, parse <memorytune/monitor> element */
+ nmons = resctrl->nmonitors;
+ if (virDomainResctrlMonDefParse(def, ctxt, node,
+ VIR_RESCTRL_MONITOR_TYPE_MEMBW,
+ resctrl) < 0)
+ goto cleanup;
+
+ nmons = resctrl->nmonitors - nmons;
+ /* Now @nmons contains the new <monitor> element number found in current
+ * <memorytune> element, and @n holds the number of new <node> element,
+ * only append the new @newresctrl object to domain if any of them is
+ * not zero. */
+ if (newresctrl && (nmons || n)) {
+ if (VIR_APPEND_ELEMENT(def->resctrls, def->nresctrls, newresctrl) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ virDomainResctrlDefFree(newresctrl);
+ return ret;
}
@@ -27607,6 +27626,7 @@ virDomainMemorytuneDefFormat(virBufferPtr buf,
{
g_auto(virBuffer) childrenBuf = VIR_BUFFER_INITIALIZER;
g_autofree char *vcpus = NULL;
+ size_t i = 0;
virBufferSetChildIndent(&childrenBuf, buf);
if (virResctrlAllocForeachMemory(resctrl->alloc,
@@ -27614,6 +27634,12 @@ virDomainMemorytuneDefFormat(virBufferPtr buf,
&childrenBuf) < 0)
return -1;
+ for (i = 0; i< resctrl->nmonitors; i++) {
+ if (virDomainResctrlMonDefFormatHelper(resctrl->monitors[i],
+ VIR_RESCTRL_MONITOR_TYPE_MEMBW,
+ &childrenBuf) < 0)
+ return -1;
+ }
if (!virBufferUse(&childrenBuf))
return 0;
diff --git a/tests/genericxml2xmlindata/memorytune.xml
b/tests/genericxml2xmlindata/memorytune.xml
index 7486b542c5..8d86ce4282 100644
--- a/tests/genericxml2xmlindata/memorytune.xml
+++ b/tests/genericxml2xmlindata/memorytune.xml
@@ -10,12 +10,17 @@
<cache id='1' level='3' type='both' size='768'
unit='KiB'/>
</cachetune>
<memorytune vcpus='0-1'>
+ <monitor vcpus='0-1'/>
<node id='0' bandwidth='20'/>
+ <monitor vcpus='0'/>
<node id='1' bandwidth='30'/>
</memorytune>
<memorytune vcpus='3'>
<node id='0' bandwidth='50'/>
</memorytune>
+ <memorytune vcpus='2'>
+ <monitor vcpus='2'/>
+ </memorytune>
</cputune>
<os>
<type arch='i686' machine='pc'>hvm</type>
diff --git a/tests/genericxml2xmloutdata/memorytune.xml
b/tests/genericxml2xmloutdata/memorytune.xml
new file mode 100644
index 0000000000..f996435a6e
--- /dev/null
+++ b/tests/genericxml2xmloutdata/memorytune.xml
@@ -0,0 +1,42 @@
+<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>
+ <cachetune vcpus='0-1'>
+ <cache id='0' level='3' type='both' size='768'
unit='KiB'/>
+ <cache id='1' level='3' type='both' size='768'
unit='KiB'/>
+ </cachetune>
+ <memorytune vcpus='0-1'>
+ <node id='0' bandwidth='20'/>
+ <node id='1' bandwidth='30'/>
+ <monitor vcpus='0-1'/>
+ <monitor vcpus='0'/>
+ </memorytune>
+ <memorytune vcpus='3'>
+ <node id='0' bandwidth='50'/>
+ </memorytune>
+ <memorytune vcpus='2'>
+ <monitor vcpus='2'/>
+ </memorytune>
+ </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-i686</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 62005a5393..93f90f7cfd 100644
--- a/tests/genericxml2xmltest.c
+++ b/tests/genericxml2xmltest.c
@@ -137,7 +137,7 @@ mymain(void)
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_FULL("cachetune-colliding-monitor", false, true,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
- DO_TEST("memorytune");
+ DO_TEST_DIFFERENT("memorytune");
DO_TEST_FULL("memorytune-colliding-allocs", false, true,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_FULL("memorytune-colliding-cachetune", false, true,
--
2.23.0