mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
conf, schema: add 'id' field for cells
In XML format, by definition, order of fields should not matter, so order of parsing the elements doesn't affect the end result. When specifying guest NUMA cells, we depend only on the order of the 'cell' elements. With this patch all older domain XMLs are parsed as before, but with the 'id' attribute they are parsed and formatted according to that field. This will be useful when we have tuning settings for particular guest NUMA node. Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
775c46956e
commit
992000e6d8
@ -1030,8 +1030,8 @@
|
|||||||
<cpu>
|
<cpu>
|
||||||
...
|
...
|
||||||
<numa>
|
<numa>
|
||||||
<cell cpus='0-3' memory='512000'/>
|
<cell id='0' cpus='0-3' memory='512000'/>
|
||||||
<cell cpus='4-7' memory='512000'/>
|
<cell id='1' cpus='4-7' memory='512000'/>
|
||||||
</numa>
|
</numa>
|
||||||
...
|
...
|
||||||
</cpu>
|
</cpu>
|
||||||
@ -1039,10 +1039,15 @@
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
Each <code>cell</code> element specifies a NUMA cell or a NUMA node.
|
Each <code>cell</code> element specifies a NUMA cell or a NUMA node.
|
||||||
<code>cpus</code> specifies the CPU or range of CPUs that are part of
|
<code>cpus</code> specifies the CPU or range of CPUs that are
|
||||||
the node. <code>memory</code> specifies the node memory in kibibytes
|
part of the node. <code>memory</code> specifies the node memory
|
||||||
(i.e. blocks of 1024 bytes). Each cell or node is assigned cellid
|
in kibibytes (i.e. blocks of 1024 bytes).
|
||||||
or nodeid in the increasing order starting from 0.
|
<span class="since">Since 1.2.7</span> all cells should
|
||||||
|
have <code>id</code> attribute in case referring to some cell is
|
||||||
|
necessary in the code, otherwise the cells are
|
||||||
|
assigned <code>id</code>s in the increasing order starting from
|
||||||
|
0. Mixing cells with and without the <code>id</code> attribute
|
||||||
|
is not recommended as it may result in unwanted behaviour.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -3927,6 +3927,11 @@
|
|||||||
|
|
||||||
<define name="numaCell">
|
<define name="numaCell">
|
||||||
<element name="cell">
|
<element name="cell">
|
||||||
|
<optional>
|
||||||
|
<attribute name="id">
|
||||||
|
<ref name="unsignedInt"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<attribute name="cpus">
|
<attribute name="cpus">
|
||||||
<ref name="cpuset"/>
|
<ref name="cpuset"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
@ -152,7 +152,6 @@ virCPUDefCopy(const virCPUDef *cpu)
|
|||||||
copy->ncells_max = copy->ncells = cpu->ncells;
|
copy->ncells_max = copy->ncells = cpu->ncells;
|
||||||
|
|
||||||
for (i = 0; i < cpu->ncells; i++) {
|
for (i = 0; i < cpu->ncells; i++) {
|
||||||
copy->cells[i].cellid = cpu->cells[i].cellid;
|
|
||||||
copy->cells[i].mem = cpu->cells[i].mem;
|
copy->cells[i].mem = cpu->cells[i].mem;
|
||||||
|
|
||||||
copy->cells[i].cpumask = virBitmapNewCopy(cpu->cells[i].cpumask);
|
copy->cells[i].cpumask = virBitmapNewCopy(cpu->cells[i].cpumask);
|
||||||
@ -438,17 +437,48 @@ virCPUDefParseXML(xmlNodePtr node,
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
char *cpus, *memory;
|
char *cpus, *memory;
|
||||||
int ret, ncpus = 0;
|
int ret, ncpus = 0;
|
||||||
|
unsigned int cur_cell;
|
||||||
|
char *tmp = NULL;
|
||||||
|
|
||||||
|
tmp = virXMLPropString(nodes[i], "id");
|
||||||
|
if (!tmp) {
|
||||||
|
cur_cell = i;
|
||||||
|
} else {
|
||||||
|
ret = virStrToLong_ui(tmp, NULL, 10, &cur_cell);
|
||||||
|
if (ret == -1) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Invalid 'id' attribute in NUMA cell: %s"),
|
||||||
|
tmp);
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur_cell >= n) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("Exactly one 'cell' element per guest "
|
||||||
|
"NUMA cell allowed, non-contiguous ranges or "
|
||||||
|
"ranges not starting from 0 are not allowed"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def->cells[cur_cell].cpustr) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
|
_("Duplicate NUMA cell info for cell id '%u'"),
|
||||||
|
cur_cell);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
def->cells[i].cellid = i;
|
|
||||||
cpus = virXMLPropString(nodes[i], "cpus");
|
cpus = virXMLPropString(nodes[i], "cpus");
|
||||||
if (!cpus) {
|
if (!cpus) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("Missing 'cpus' attribute in NUMA cell"));
|
_("Missing 'cpus' attribute in NUMA cell"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
def->cells[i].cpustr = cpus;
|
def->cells[cur_cell].cpustr = cpus;
|
||||||
|
|
||||||
ncpus = virBitmapParse(cpus, 0, &def->cells[i].cpumask,
|
ncpus = virBitmapParse(cpus, 0, &def->cells[cur_cell].cpumask,
|
||||||
VIR_DOMAIN_CPUMASK_LEN);
|
VIR_DOMAIN_CPUMASK_LEN);
|
||||||
if (ncpus <= 0)
|
if (ncpus <= 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -461,7 +491,7 @@ virCPUDefParseXML(xmlNodePtr node,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = virStrToLong_ui(memory, NULL, 10, &def->cells[i].mem);
|
ret = virStrToLong_ui(memory, NULL, 10, &def->cells[cur_cell].mem);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("Invalid 'memory' attribute in NUMA cell"));
|
_("Invalid 'memory' attribute in NUMA cell"));
|
||||||
@ -645,6 +675,7 @@ virCPUDefFormatBuf(virBufferPtr buf,
|
|||||||
virBufferAdjustIndent(buf, 2);
|
virBufferAdjustIndent(buf, 2);
|
||||||
for (i = 0; i < def->ncells; i++) {
|
for (i = 0; i < def->ncells; i++) {
|
||||||
virBufferAddLit(buf, "<cell");
|
virBufferAddLit(buf, "<cell");
|
||||||
|
virBufferAsprintf(buf, " id='%zu'", i);
|
||||||
virBufferAsprintf(buf, " cpus='%s'", def->cells[i].cpustr);
|
virBufferAsprintf(buf, " cpus='%s'", def->cells[i].cpustr);
|
||||||
virBufferAsprintf(buf, " memory='%d'", def->cells[i].mem);
|
virBufferAsprintf(buf, " memory='%d'", def->cells[i].mem);
|
||||||
virBufferAddLit(buf, "/>\n");
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* cpu_conf.h: CPU XML handling
|
* cpu_conf.h: CPU XML handling
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009-2011, 2013 Red Hat, Inc.
|
* Copyright (C) 2009-2011, 2013, 2014 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -93,7 +93,6 @@ struct _virCPUFeatureDef {
|
|||||||
typedef struct _virCellDef virCellDef;
|
typedef struct _virCellDef virCellDef;
|
||||||
typedef virCellDef *virCellDefPtr;
|
typedef virCellDef *virCellDefPtr;
|
||||||
struct _virCellDef {
|
struct _virCellDef {
|
||||||
int cellid;
|
|
||||||
virBitmapPtr cpumask; /* CPUs that are part of this node */
|
virBitmapPtr cpumask; /* CPUs that are part of this node */
|
||||||
char *cpustr; /* CPUs stored in string form for dumpxml */
|
char *cpustr; /* CPUs stored in string form for dumpxml */
|
||||||
unsigned int mem; /* Node memory in kB */
|
unsigned int mem; /* Node memory in kB */
|
||||||
|
@ -6400,7 +6400,7 @@ qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
virCommandAddArg(cmd, "-numa");
|
virCommandAddArg(cmd, "-numa");
|
||||||
virBufferAsprintf(&buf, "node,nodeid=%d", def->cpu->cells[i].cellid);
|
virBufferAsprintf(&buf, "node,nodeid=%zu", i);
|
||||||
virBufferAddLit(&buf, ",cpus=");
|
virBufferAddLit(&buf, ",cpus=");
|
||||||
|
|
||||||
/* Up through qemu 1.4, -numa does not accept a cpus
|
/* Up through qemu 1.4, -numa does not accept a cpus
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
<boot dev='network'/>
|
<boot dev='network'/>
|
||||||
</os>
|
</os>
|
||||||
<cpu>
|
<cpu>
|
||||||
<topology sockets="2" cores="4" threads="2"/>
|
<topology sockets='2' cores='4' threads='2'/>
|
||||||
<numa>
|
<numa>
|
||||||
<cell cpus="0-7" memory="109550"/>
|
<cell cpus='0-7' memory='109550'/>
|
||||||
<cell cpus="8-15" memory="109550"/>
|
<cell cpus='8-15' memory='109550'/>
|
||||||
</numa>
|
</numa>
|
||||||
</cpu>
|
</cpu>
|
||||||
<clock offset='utc'/>
|
<clock offset='utc'/>
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
<boot dev='network'/>
|
<boot dev='network'/>
|
||||||
</os>
|
</os>
|
||||||
<cpu>
|
<cpu>
|
||||||
<topology sockets="2" cores="4" threads="2"/>
|
<topology sockets='2' cores='4' threads='2'/>
|
||||||
<numa>
|
<numa>
|
||||||
<cell cpus="0-7" memory="109550"/>
|
<cell id='1' cpus='8-15' memory='109550'/>
|
||||||
<cell cpus="8-15" memory="109550"/>
|
<cell id='0' cpus='0-7' memory='109550'/>
|
||||||
</numa>
|
</numa>
|
||||||
</cpu>
|
</cpu>
|
||||||
<clock offset='utc'/>
|
<clock offset='utc'/>
|
||||||
|
25
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
Normal file
25
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>219100</memory>
|
||||||
|
<currentMemory unit='KiB'>219100</currentMemory>
|
||||||
|
<vcpu placement='static'>16</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
<boot dev='network'/>
|
||||||
|
</os>
|
||||||
|
<cpu>
|
||||||
|
<topology sockets='2' cores='4' threads='2'/>
|
||||||
|
<numa>
|
||||||
|
<cell id='1' cpus='0-7' memory='109550'/>
|
||||||
|
<cell id='2' cpus='8-15' memory='109550'/>
|
||||||
|
</numa>
|
||||||
|
</cpu>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -1178,6 +1178,7 @@ mymain(void)
|
|||||||
DO_TEST("cpu-strict1", NONE);
|
DO_TEST("cpu-strict1", NONE);
|
||||||
DO_TEST("cpu-numa1", NONE);
|
DO_TEST("cpu-numa1", NONE);
|
||||||
DO_TEST("cpu-numa2", QEMU_CAPS_SMP_TOPOLOGY);
|
DO_TEST("cpu-numa2", QEMU_CAPS_SMP_TOPOLOGY);
|
||||||
|
DO_TEST_PARSE_ERROR("cpu-numa3", NONE);
|
||||||
DO_TEST("cpu-host-model", NONE);
|
DO_TEST("cpu-host-model", NONE);
|
||||||
skipLegacyCPUs = true;
|
skipLegacyCPUs = true;
|
||||||
DO_TEST("cpu-host-model-fallback", NONE);
|
DO_TEST("cpu-host-model-fallback", NONE);
|
||||||
|
28
tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml
Normal file
28
tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>219100</memory>
|
||||||
|
<currentMemory unit='KiB'>219100</currentMemory>
|
||||||
|
<vcpu placement='static'>16</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
<boot dev='network'/>
|
||||||
|
</os>
|
||||||
|
<cpu>
|
||||||
|
<topology sockets='2' cores='4' threads='2'/>
|
||||||
|
<numa>
|
||||||
|
<cell id='0' cpus='0-7' memory='109550'/>
|
||||||
|
<cell id='1' cpus='8-15' memory='109550'/>
|
||||||
|
</numa>
|
||||||
|
</cpu>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<controller type='usb' index='0'/>
|
||||||
|
<controller type='pci' index='0' model='pci-root'/>
|
||||||
|
<memballoon model='virtio'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
28
tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml
Normal file
28
tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>219100</memory>
|
||||||
|
<currentMemory unit='KiB'>219100</currentMemory>
|
||||||
|
<vcpu placement='static'>16</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='pc'>hvm</type>
|
||||||
|
<boot dev='network'/>
|
||||||
|
</os>
|
||||||
|
<cpu>
|
||||||
|
<topology sockets='2' cores='4' threads='2'/>
|
||||||
|
<numa>
|
||||||
|
<cell id='0' cpus='0-7' memory='109550'/>
|
||||||
|
<cell id='1' cpus='8-15' memory='109550'/>
|
||||||
|
</numa>
|
||||||
|
</cpu>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<controller type='usb' index='0'/>
|
||||||
|
<controller type='pci' index='0' model='pci-root'/>
|
||||||
|
<memballoon model='virtio'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -370,6 +370,9 @@ mymain(void)
|
|||||||
|
|
||||||
DO_TEST("chardev-label");
|
DO_TEST("chardev-label");
|
||||||
|
|
||||||
|
DO_TEST_DIFFERENT("cpu-numa1");
|
||||||
|
DO_TEST_DIFFERENT("cpu-numa2");
|
||||||
|
|
||||||
virObjectUnref(driver.caps);
|
virObjectUnref(driver.caps);
|
||||||
virObjectUnref(driver.xmlopt);
|
virObjectUnref(driver.xmlopt);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user