diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index d8206564aa..8c03ebb053 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1141,7 +1141,7 @@ ... <numa> <cell id='0' cpus='0-3' memory='512000'/> - <cell id='1' cpus='4-7' memory='512000'/> + <cell id='1' cpus='4-7' memory='512000' memAccess='shared'/> </numa> ... </cpu> @@ -1158,6 +1158,11 @@ assigned ids in the increasing order starting from 0. Mixing cells with and without the id attribute is not recommended as it may result in unwanted behaviour. + + Since 1.2.9 the optional attribute + memAccess can control whether the memory is to be + mapped as "shared" or "private". This is valid only for + hugepages-backed memory.

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 9945700626..19dc82f16e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4030,6 +4030,14 @@ + + + + shared + private + + + diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index 5003cf164c..e190641e80 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -56,6 +56,11 @@ VIR_ENUM_IMPL(virCPUFeaturePolicy, VIR_CPU_FEATURE_LAST, "disable", "forbid") +VIR_ENUM_IMPL(virMemAccess, VIR_MEM_ACCESS_LAST, + "default", + "shared", + "private") + void ATTRIBUTE_NONNULL(1) virCPUDefFreeModel(virCPUDefPtr def) @@ -435,7 +440,7 @@ virCPUDefParseXML(xmlNodePtr node, def->ncells = n; for (i = 0; i < n; i++) { - char *cpus, *memory; + char *cpus, *memory, *memAccessStr; int ret, ncpus = 0; unsigned int cur_cell; char *tmp = NULL; @@ -491,7 +496,7 @@ virCPUDefParseXML(xmlNodePtr node, goto error; } - ret = virStrToLong_ui(memory, NULL, 10, &def->cells[cur_cell].mem); + ret = virStrToLong_ui(memory, NULL, 10, &def->cells[cur_cell].mem); if (ret == -1) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Invalid 'memory' attribute in NUMA cell")); @@ -499,6 +504,22 @@ virCPUDefParseXML(xmlNodePtr node, goto error; } VIR_FREE(memory); + + memAccessStr = virXMLPropString(nodes[i], "memAccess"); + if (memAccessStr) { + def->cells[cur_cell].memAccess = + virMemAccessTypeFromString(memAccessStr); + + if (def->cells[cur_cell].memAccess <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid 'memAccess' attribute " + "value '%s'"), + memAccessStr); + VIR_FREE(memAccessStr); + goto cleanup; + } + VIR_FREE(memAccessStr); + } } } @@ -674,10 +695,15 @@ virCPUDefFormatBuf(virBufferPtr buf, virBufferAddLit(buf, "\n"); virBufferAdjustIndent(buf, 2); for (i = 0; i < def->ncells; i++) { + virMemAccess memAccess = def->cells[i].memAccess; + virBufferAddLit(buf, "cells[i].cpustr); virBufferAsprintf(buf, " memory='%d'", def->cells[i].mem); + if (memAccess) + virBufferAsprintf(buf, " memAccess='%s'", + virMemAccessTypeToString(memAccess)); virBufferAddLit(buf, "/>\n"); } virBufferAdjustIndent(buf, -2); diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h index 2d538db5db..d45210be3e 100644 --- a/src/conf/cpu_conf.h +++ b/src/conf/cpu_conf.h @@ -83,6 +83,16 @@ typedef enum { VIR_ENUM_DECL(virCPUFeaturePolicy) +typedef enum { + VIR_MEM_ACCESS_DEFAULT, + VIR_MEM_ACCESS_SHARED, + VIR_MEM_ACCESS_PRIVATE, + + VIR_MEM_ACCESS_LAST, +} virMemAccess; + +VIR_ENUM_DECL(virMemAccess) + typedef struct _virCPUFeatureDef virCPUFeatureDef; typedef virCPUFeatureDef *virCPUFeatureDefPtr; struct _virCPUFeatureDef { @@ -93,9 +103,10 @@ struct _virCPUFeatureDef { typedef struct _virCellDef virCellDef; typedef virCellDef *virCellDefPtr; struct _virCellDef { - virBitmapPtr cpumask; /* CPUs that are part of this node */ - char *cpustr; /* CPUs stored in string form for dumpxml */ - unsigned int mem; /* Node memory in kB */ + virBitmapPtr cpumask; /* CPUs that are part of this node */ + char *cpustr; /* CPUs stored in string form for dumpxml */ + unsigned int mem; /* Node memory in kB */ + virMemAccess memAccess; }; typedef struct _virCPUDef virCPUDef; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.xml new file mode 100644 index 0000000000..cf7c040ccc --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-memshared.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 16 + + hvm + + + + + + + + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-shared.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-shared.xml new file mode 100644 index 0000000000..e7db69c5a5 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-shared.xml @@ -0,0 +1,45 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 4194304 + 4194304 + + + + + + + 4 + + + + + + hvm + + + + + + + + + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +

+ + + + + + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index ead5d082e3..675403a1ff 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -205,6 +205,7 @@ mymain(void) DO_TEST("hugepages-pages"); DO_TEST("hugepages-pages2"); DO_TEST("hugepages-pages3"); + DO_TEST("hugepages-shared"); DO_TEST("nosharepages"); DO_TEST("disk-aio"); DO_TEST("disk-cdrom"); @@ -392,6 +393,7 @@ mymain(void) DO_TEST_DIFFERENT("cpu-numa1"); DO_TEST_DIFFERENT("cpu-numa2"); DO_TEST("cpu-numa-disjoint"); + DO_TEST("cpu-numa-memshared"); DO_TEST_DIFFERENT("numatune-auto-prefer"); DO_TEST_DIFFERENT("numatune-memnode");