[libvirt] [PATCH 0/3] Add support for preallocated fd memory

Hi, we would like to introduce 3 new elements source,access and allocation in memoryBacking element. <memoryBacking> <source type="file|anonymous"/> <access Mode="shared|private"/> <allocation mode="immediate|ondemand"/> </memoryBacking> If allocation is immediate then -mem-prealloc should be added to the qemu commanline. If source is file then -object memory-backend-file,id=mem,size=1024M,mem-path=/var/lib/libvirt/qemu -numa node,memdev=mem Should be added to the qemu commandline If access is shared then the share=on parameter should be added to the memory-backend-file e.g. -object memory-backend-file,id=mem,size=1024M,mem-path=/var/lib/libvirt/qemu,share=on Also token memAccess in numa cell is used (if not present, default value from memoryBacking is used) Jaroslav Safka (3): Add support for preallocated fd memory Add support for preallocated fd memory Add support for preallocated fd memory - doc docs/formatdomain.html.in | 10 ++ docs/schemas/domaincommon.rng | 30 ++++ src/conf/domain_conf.c | 138 +++++++++++++----- src/conf/domain_conf.h | 33 +++++ src/qemu/qemu_command.c | 156 ++++++++++++++++----- src/qemu/qemu_command.h | 4 + .../qemuxml2argv-fd-memory-no-numa-topology.args | 33 +++++ .../qemuxml2argv-fd-memory-no-numa-topology.xml | 91 ++++++++++++ .../qemuxml2argv-fd-memory-numa-topology.args | 33 +++++ .../qemuxml2argv-fd-memory-numa-topology.xml | 94 +++++++++++++ .../qemuxml2argv-fd-memory-numa-topology2.args | 36 +++++ .../qemuxml2argv-fd-memory-numa-topology2.xml | 95 +++++++++++++ .../qemuxml2argv-fd-memory-numa-topology3.args | 39 ++++++ .../qemuxml2argv-fd-memory-numa-topology3.xml | 96 +++++++++++++ .../qemuxml2argv-memorybacking-set.xml | 32 +++++ .../qemuxml2argv-memorybacking-unset.xml | 32 +++++ tests/qemuxml2argvtest.c | 42 ++++++ .../qemuxml2xmlout-memorybacking-set.xml | 40 ++++++ .../qemuxml2xmlout-memorybacking-unset.xml | 40 ++++++ tests/qemuxml2xmltest.c | 3 + 20 files changed, 1011 insertions(+), 66 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml -- 2.7.4 -------------------------------------------------------------- Intel Research and Development Ireland Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

This first change introduces xml parsing support for preallocated shared file descriptor based memory backing. It allows vhost-user to be used without hugepages. New xml elements: <memoryBacking> <source type='file|anonymous'/> <access mode='shared|private'/> <allocation mode='immediate|ondemand'/> </memoryBacking> --- docs/schemas/domaincommon.rng | 30 +++++ src/conf/domain_conf.c | 138 ++++++++++++++++----- src/conf/domain_conf.h | 33 +++++ .../qemuxml2xmlout-memorybacking-set.xml | 40 ++++++ .../qemuxml2xmlout-memorybacking-unset.xml | 40 ++++++ tests/qemuxml2xmltest.c | 3 + 6 files changed, 251 insertions(+), 33 deletions(-) create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index dba9187..46d0be5 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -559,6 +559,36 @@ <empty/> </element> </optional> + <optional> + <element name="source"> + <attribute name="type"> + <choice> + <value>file</value> + <value>anonymous</value> + </choice> + </attribute> + </element> + </optional> + <optional> + <element name="access"> + <attribute name="mode"> + <choice> + <value>shared</value> + <value>private</value> + </choice> + </attribute> + </element> + </optional> + <optional> + <element name="allocation"> + <attribute name="mode"> + <choice> + <value>immediate</value> + <value>ondemand</value> + </choice> + </attribute> + </element> + </optional> </interleave> </element> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 03506cb..97ef769 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -830,6 +830,21 @@ VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST, "abort", "pivot") +VIR_ENUM_IMPL(virDomainMemorySource, VIR_DOMAIN_MEMORY_SOURCE_LAST, + "none", + "file", + "anonymous") + +VIR_ENUM_IMPL(virDomainMemoryAccess, VIR_DOMAIN_MEMORY_ACCESS_LAST, + "none", + "shared", + "private") + +VIR_ENUM_IMPL(virDomainMemoryAllocation, VIR_DOMAIN_MEMORY_ALLOCATION_LAST, + "none", + "immediate", + "ondemand") + VIR_ENUM_IMPL(virDomainLoader, VIR_DOMAIN_LOADER_TYPE_LAST, "rom", @@ -16291,48 +16306,93 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(tmp); - if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot extract hugepages nodes")); - goto error; + tmp = virXPathString("string(./memoryBacking/source/@type)", ctxt); + if (tmp) { + if ((def->mem.source = virDomainMemorySourceTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/source/type '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); } - if (n) { - if (VIR_ALLOC_N(def->mem.hugepages, n) < 0) + tmp = virXPathString("string(./memoryBacking/access/@mode)", ctxt); + if (tmp) { + if ((def->mem.access = virDomainMemoryAccessTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/access/mode '%s'"), tmp); goto error; + } + VIR_FREE(tmp); + } - for (i = 0; i < n; i++) { - if (virDomainHugepagesParseXML(nodes[i], ctxt, - &def->mem.hugepages[i]) < 0) + tmp = virXPathString("string(./memoryBacking/allocation/@mode)", ctxt); + if (tmp) { + if ((def->mem.allocation = virDomainMemoryAllocationTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/allocation/mode '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + } + + if (virXPathNode("./memoryBacking/hugepages", ctxt)) { + /* hugepages will be used */ + + if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_ONDEMAND) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("hugepages are not allowed with memory allocation ondemand")); + goto error; + } + + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("hugepages are not allowed with anonymous memory source")); + goto error; + } + + if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot extract hugepages nodes")); + goto error; + } + + if (n) { + if (VIR_ALLOC_N(def->mem.hugepages, n) < 0) goto error; - def->mem.nhugepages++; - for (j = 0; j < i; j++) { - if (def->mem.hugepages[i].nodemask && - def->mem.hugepages[j].nodemask && - virBitmapOverlaps(def->mem.hugepages[i].nodemask, - def->mem.hugepages[j].nodemask)) { - virReportError(VIR_ERR_XML_DETAIL, - _("nodeset attribute of hugepages " - "of sizes %llu and %llu intersect"), - def->mem.hugepages[i].size, - def->mem.hugepages[j].size); - goto error; - } else if (!def->mem.hugepages[i].nodemask && - !def->mem.hugepages[j].nodemask) { - virReportError(VIR_ERR_XML_DETAIL, - _("two master hugepages detected: " - "%llu and %llu"), - def->mem.hugepages[i].size, - def->mem.hugepages[j].size); + for (i = 0; i < n; i++) { + if (virDomainHugepagesParseXML(nodes[i], ctxt, + &def->mem.hugepages[i]) < 0) goto error; + def->mem.nhugepages++; + + for (j = 0; j < i; j++) { + if (def->mem.hugepages[i].nodemask && + def->mem.hugepages[j].nodemask && + virBitmapOverlaps(def->mem.hugepages[i].nodemask, + def->mem.hugepages[j].nodemask)) { + virReportError(VIR_ERR_XML_DETAIL, + _("nodeset attribute of hugepages " + "of sizes %llu and %llu intersect"), + def->mem.hugepages[i].size, + def->mem.hugepages[j].size); + goto error; + } else if (!def->mem.hugepages[i].nodemask && + !def->mem.hugepages[j].nodemask) { + virReportError(VIR_ERR_XML_DETAIL, + _("two master hugepages detected: " + "%llu and %llu"), + def->mem.hugepages[i].size, + def->mem.hugepages[j].size); + goto error; + } } } - } - VIR_FREE(nodes); - } else { - if ((node = virXPathNode("./memoryBacking/hugepages", ctxt))) { + VIR_FREE(nodes); + } else { + /* no hugepage pages */ if (VIR_ALLOC(def->mem.hugepages) < 0) goto error; @@ -23539,7 +23599,9 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAddLit(buf, "</memtune>\n"); } - if (def->mem.nhugepages || def->mem.nosharepages || def->mem.locked) { + if (def->mem.nhugepages || def->mem.nosharepages || def->mem.locked + || def->mem.source || def->mem.access || def->mem.allocation) + { virBufferAddLit(buf, "<memoryBacking>\n"); virBufferAdjustIndent(buf, 2); if (def->mem.nhugepages) @@ -23548,6 +23610,16 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAddLit(buf, "<nosharepages/>\n"); if (def->mem.locked) virBufferAddLit(buf, "<locked/>\n"); + if (def->mem.source) + virBufferAsprintf(buf, "<source type='%s'/>\n", + virDomainMemorySourceTypeToString(def->mem.source)); + if (def->mem.access) + virBufferAsprintf(buf, "<access mode='%s'/>\n", + virDomainMemoryAccessTypeToString(def->mem.access)); + if (def->mem.allocation) + virBufferAsprintf(buf, "<allocation mode='%s'/>\n", + virDomainMemoryAllocationTypeToString(def->mem.allocation)); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</memoryBacking>\n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 24aa79c..f50b575 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -567,6 +567,32 @@ typedef enum { VIR_DOMAIN_DISK_MIRROR_STATE_LAST } virDomainDiskMirrorState; +# define VIR_DOMAIN_MEMORY_DEFAULT_PATH "/var/lib/libvirt/qemu" + +typedef enum { + VIR_DOMAIN_MEMORY_SOURCE_NONE = 0, /* No memory source defined */ + VIR_DOMAIN_MEMORY_SOURCE_FILE, /* Memory source is set as file */ + VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS, /* Memory source is set as anonymous */ + + VIR_DOMAIN_MEMORY_SOURCE_LAST, +} virDomainMemorySource; + +typedef enum { + VIR_DOMAIN_MEMORY_ACCESS_NONE = 0, /* No memory access defined */ + VIR_DOMAIN_MEMORY_ACCESS_SHARED, /* Memory access is set as shared */ + VIR_DOMAIN_MEMORY_ACCESS_PRIVATE, /* Memory access is set as private */ + + VIR_DOMAIN_MEMORY_ACCESS_LAST, +} virDomainMemoryAccess; + +typedef enum { + VIR_DOMAIN_MEMORY_ALLOCATION_NONE = 0, /* No memory allocation defined */ + VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE, /* Memory allocation is set as immediate */ + VIR_DOMAIN_MEMORY_ALLOCATION_ONDEMAND, /* Memory allocation is set as ondemand */ + + VIR_DOMAIN_MEMORY_ALLOCATION_LAST, +} virDomainMemoryAllocation; + /* Stores the virtual disk configuration */ struct _virDomainDiskDef { @@ -2100,6 +2126,10 @@ struct _virDomainMemtune { unsigned long long soft_limit; /* in kibibytes, limit at off_t bytes */ unsigned long long min_guarantee; /* in kibibytes, limit at off_t bytes */ unsigned long long swap_hard_limit; /* in kibibytes, limit at off_t bytes */ + + int source; /* enum virDomainMemorySource */ + int access; /* enum virDomainMemoryAccess */ + int allocation; /* enum virDomainMemoryAllocation */ }; typedef struct _virDomainPowerManagement virDomainPowerManagement; @@ -3083,6 +3113,9 @@ VIR_ENUM_DECL(virDomainTPMModel) VIR_ENUM_DECL(virDomainTPMBackend) VIR_ENUM_DECL(virDomainMemoryModel) VIR_ENUM_DECL(virDomainMemoryBackingModel) +VIR_ENUM_DECL(virDomainMemorySource) +VIR_ENUM_DECL(virDomainMemoryAccess) +VIR_ENUM_DECL(virDomainMemoryAllocation) VIR_ENUM_DECL(virDomainIOMMUModel) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml new file mode 100644 index 0000000..f63ae38 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml @@ -0,0 +1,40 @@ +<domain type='qemu'> + <name>SomeDummyHugepagesGuest</name> + <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='shared'/> + <allocation mode='immediate'/> + </memoryBacking> + <vcpu placement='static'>2</vcpu> + <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</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml new file mode 100644 index 0000000..7de9ffb --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml @@ -0,0 +1,40 @@ +<domain type='qemu'> + <name>SomeDummyHugepagesGuest</name> + <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <memoryBacking> + <source type='anonymous'/> + <access mode='private'/> + <allocation mode='ondemand'/> + </memoryBacking> + <vcpu placement='static'>2</vcpu> + <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</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 496ed13..7e92ca3 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -879,6 +879,9 @@ mymain(void) DO_TEST("virtio-input", NONE); DO_TEST("virtio-input-passthrough", NONE); + DO_TEST("memorybacking-set", NONE); + DO_TEST("memorybacking-unset", NONE); + virObjectUnref(cfg); DO_TEST("acpi-table", NONE); -- 2.7.4 -------------------------------------------------------------- Intel Research and Development Ireland Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

On Tue, Nov 01, 2016 at 12:11:14PM +0000, Jaroslav Safka wrote:
This first change introduces xml parsing support for preallocated shared file descriptor based memory backing. It allows vhost-user to be used without hugepages.
New xml elements: <memoryBacking> <source type='file|anonymous'/> <access mode='shared|private'/> <allocation mode='immediate|ondemand'/> </memoryBacking> --- docs/schemas/domaincommon.rng | 30 +++++ src/conf/domain_conf.c | 138 ++++++++++++++++----- src/conf/domain_conf.h | 33 +++++ .../qemuxml2xmlout-memorybacking-set.xml | 40 ++++++ .../qemuxml2xmlout-memorybacking-unset.xml | 40 ++++++ tests/qemuxml2xmltest.c | 3 + 6 files changed, 251 insertions(+), 33 deletions(-) create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml
Tests will fail after this patch, the source files for the tests are missing.
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 03506cb..97ef769 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -830,6 +830,21 @@ VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST, "abort", "pivot")
+VIR_ENUM_IMPL(virDomainMemorySource, VIR_DOMAIN_MEMORY_SOURCE_LAST, + "none", + "file", + "anonymous") + +VIR_ENUM_IMPL(virDomainMemoryAccess, VIR_DOMAIN_MEMORY_ACCESS_LAST, + "none", + "shared", + "private") +
This is the same as virNumaMemAccess from numa_conf.c, you should change that one to this type so it's not duplicated.
+VIR_ENUM_IMPL(virDomainMemoryAllocation, VIR_DOMAIN_MEMORY_ALLOCATION_LAST, + "none", + "immediate", + "ondemand") + VIR_ENUM_IMPL(virDomainLoader, VIR_DOMAIN_LOADER_TYPE_LAST, "rom", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 24aa79c..f50b575 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -567,6 +567,32 @@ typedef enum { VIR_DOMAIN_DISK_MIRROR_STATE_LAST } virDomainDiskMirrorState;
+# define VIR_DOMAIN_MEMORY_DEFAULT_PATH "/var/lib/libvirt/qemu" +
This is wrong. You should use domain's priv->libDir which is per-domain directory which is properly labelled and configurable. Also it is handled so that it works on upgrades, etc.
+typedef enum { + VIR_DOMAIN_MEMORY_SOURCE_NONE = 0, /* No memory source defined */ + VIR_DOMAIN_MEMORY_SOURCE_FILE, /* Memory source is set as file */ + VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS, /* Memory source is set as anonymous */ + + VIR_DOMAIN_MEMORY_SOURCE_LAST, +} virDomainMemorySource; + +typedef enum { + VIR_DOMAIN_MEMORY_ACCESS_NONE = 0, /* No memory access defined */ + VIR_DOMAIN_MEMORY_ACCESS_SHARED, /* Memory access is set as shared */ + VIR_DOMAIN_MEMORY_ACCESS_PRIVATE, /* Memory access is set as private */ + + VIR_DOMAIN_MEMORY_ACCESS_LAST, +} virDomainMemoryAccess; +
Same here for the virNumaMemAccess, of course.

This second change introduces support for preallocated shared file descriptor based memory backing. It allows vhost-user to be used without hugepages. Also token memAccess in numa cell is used (if not present, default value from memoryBacking is used) Used xml elements: <memoryBacking> <source type='file|anonymous'/> <access Mode='shared|private'/> <allocation mode='immediate|ondemand'/> </memoryBacking> --- src/qemu/qemu_command.c | 156 ++++++++++++++++----- src/qemu/qemu_command.h | 4 + .../qemuxml2argv-fd-memory-no-numa-topology.args | 33 +++++ .../qemuxml2argv-fd-memory-no-numa-topology.xml | 91 ++++++++++++ .../qemuxml2argv-fd-memory-numa-topology.args | 33 +++++ .../qemuxml2argv-fd-memory-numa-topology.xml | 94 +++++++++++++ .../qemuxml2argv-fd-memory-numa-topology2.args | 36 +++++ .../qemuxml2argv-fd-memory-numa-topology2.xml | 95 +++++++++++++ .../qemuxml2argv-fd-memory-numa-topology3.args | 39 ++++++ .../qemuxml2argv-fd-memory-numa-topology3.xml | 96 +++++++++++++ .../qemuxml2argv-memorybacking-set.xml | 32 +++++ .../qemuxml2argv-memorybacking-unset.xml | 32 +++++ tests/qemuxml2argvtest.c | 42 ++++++ 13 files changed, 750 insertions(+), 33 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b68da3d..7710864 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3283,15 +3283,11 @@ qemuBuildMemoryBackendStr(unsigned long long size, if (!(props = virJSONValueNewObject())) return -1; - if (pagesize) { - if (qemuGetHupageMemPath(cfg, pagesize, &mem_path) < 0) - goto cleanup; - + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) { *backendType = "memory-backend-file"; if (virJSONValueObjectAdd(props, - "b:prealloc", true, - "s:mem-path", mem_path, + "s:mem-path", VIR_DOMAIN_MEMORY_DEFAULT_PATH, NULL) < 0) goto cleanup; @@ -3307,18 +3303,61 @@ qemuBuildMemoryBackendStr(unsigned long long size, break; case VIR_NUMA_MEM_ACCESS_DEFAULT: + if (def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED) { + if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0) + goto cleanup; + } + break; + case VIR_NUMA_MEM_ACCESS_LAST: break; } + + force = true; } else { - if (memAccess) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Shared memory mapping is supported " - "only with hugepages")); - goto cleanup; - } + if (pagesize) { + if (qemuGetHupageMemPath(cfg, pagesize, &mem_path) < 0) + goto cleanup; - *backendType = "memory-backend-ram"; + *backendType = "memory-backend-file"; + + if (virJSONValueObjectAdd(props, + "b:prealloc", true, + "s:mem-path", mem_path, + NULL) < 0) + goto cleanup; + + switch (memAccess) { + case VIR_NUMA_MEM_ACCESS_SHARED: + if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0) + goto cleanup; + break; + + case VIR_NUMA_MEM_ACCESS_PRIVATE: + if (virJSONValueObjectAdd(props, "b:share", false, NULL) < 0) + goto cleanup; + break; + + case VIR_NUMA_MEM_ACCESS_DEFAULT: + if (def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED) { + if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0) + goto cleanup; + } + break; + + case VIR_NUMA_MEM_ACCESS_LAST: + break; + } + } else { + if (memAccess) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Shared memory mapping is supported " + "only with hugepages")); + goto cleanup; + } + + *backendType = "memory-backend-ram"; + } } if (virJSONValueObjectAdd(props, "U:size", size * 1024, NULL) < 0) @@ -7138,28 +7177,35 @@ qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, const long system_page_size = virGetSystemPageSizeKB(); char *mem_path = NULL; - /* - * No-op if hugepages were not requested. - */ - if (!def->mem.nhugepages) + if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) { + virCommandAddArgList(cmd, "-mem-prealloc", NULL); return 0; + } - /* There is one special case: if user specified "huge" - * pages of regular system pages size. - * And there is nothing to do in this case. - */ - if (def->mem.hugepages[0].size == system_page_size) - return 0; + if (def->mem.nhugepages) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("hugepage backing not supported by '%s'"), - def->emulator); - return -1; - } + /* There is one special case: if user specified "huge" + * pages of regular system pages size. + * And there is nothing to do in this case. + */ + if (def->mem.hugepages[0].size == system_page_size) + return 0; - if (qemuGetHupageMemPath(cfg, def->mem.hugepages[0].size, &mem_path) < 0) - return -1; + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("hugepage backing not supported by '%s'"), + def->emulator); + return -1; + } + + if (qemuGetHupageMemPath(cfg, def->mem.hugepages[0].size, &mem_path) < 0) + return -1; + } else { + /* + * No-op if hugepages or immediate allocation were not requested. + */ + return 0; + } virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path", mem_path, NULL); VIR_FREE(mem_path); @@ -7195,8 +7241,9 @@ qemuBuildMemCommandLine(virCommandPtr cmd, * Add '-mem-path' (and '-mem-prealloc') parameter here only if * there is no numa node specified. */ - if (!virDomainNumaGetNodeCount(def->numa) && - qemuBuildMemPathStr(cfg, def, qemuCaps, cmd) < 0) + if ((!virDomainNumaGetNodeCount(def->numa) + || def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) + && qemuBuildMemPathStr(cfg, def, qemuCaps, cmd) < 0) return -1; if (def->mem.locked && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_REALTIME_MLOCK)) { @@ -9424,6 +9471,10 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, qemuBuildNumaArgStr(cfg, def, cmd, qemuCaps, nodeset) < 0) goto error; + if (!virDomainNumaGetNodeCount(def->numa) && + qemuBuildMemoryBackingCommandLine(def, cmd, qemuCaps) < 0) + goto error; + if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, qemuCaps, nodeset) < 0) goto error; @@ -9816,6 +9867,45 @@ qemuBuildChrDeviceStr(char **deviceStr, return ret; } +int +qemuBuildMemoryBackingCommandLine(const virDomainDef *def, + virCommandPtr cmd, + virQEMUCapsPtr qemuCaps) +{ + int ret = -1; + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *alias = "ram"; + + if (def->mem.source != VIR_DOMAIN_MEMORY_SOURCE_FILE) { + ret = 0; + goto cleanup; + } + /* numa is disabled and mem source is file */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("File memory mapping is not supported " + "with this QEMU")); + goto cleanup; + } + + virCommandAddArg(cmd, "-object"); + virBufferAsprintf(&buf, "memory-backend-file,id=%s,mem-path=%s,", alias, VIR_DOMAIN_MEMORY_DEFAULT_PATH); + + if (def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED) + virBufferAsprintf(&buf, "%s", "share=yes,"); + + virBufferAsprintf(&buf, "size=%llu", virDomainDefGetMemoryInitial(def) / 1024); + virCommandAddArgBuffer(cmd, &buf); + + virCommandAddArg(cmd, "-numa"); + virCommandAddArgFormat(cmd, "node,memdev=%s", alias); + + ret = 0; + cleanup: + + virBufferFreeAndReset(&buf); + return ret; +} virJSONValuePtr diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index a793fb6..c0ecd62 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -183,6 +183,10 @@ bool qemuCheckCCWS390AddressSupport(const virDomainDef *def, virDomainDeviceInfo info, virQEMUCapsPtr qemuCaps, const char *devicename); +int +qemuBuildMemoryBackingCommandLine(const virDomainDef *def, + virCommandPtr cmd, + virQEMUCapsPtr qemuCaps); virJSONValuePtr qemuBuildHotpluggableCPUProps(const virDomainVcpuDef *vcpu) ATTRIBUTE_NONNULL(1); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args new file mode 100644 index 0000000..1563693 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args @@ -0,0 +1,33 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name instance-00000092 \ +-S \ +-M pc-i440fx-wily \ +-cpu host \ +-m 14336 \ +-mem-prealloc \ +-smp 8,sockets=8,cores=1,threads=1 \ +-object memory-backend-file,id=ram,mem-path=/var/lib/libvirt/qemu,share=yes,\ +size=14336 \ +-numa node,memdev=ram \ +-uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ +-smbios 'type=1,manufacturer=OpenStack Foundation,product=OpenStack Nova,\ +version=13.0.0,serial=0640ddd5-36c9-e211-a2f6-001e6789a0f1,\ +uuid=126f2720-6f8e-45ab-a886-ec9277079a67,family=Virtual Machine' \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-instance-00000092/monitor.sock,server,nowait \ +-rtc base=utc,driftfix=slew \ +-no-kvm-pit-reinjection \ +-boot c \ +-usb \ +-drive file=/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk,\ +format=qcow2,if=none,id=drive-virtio-disk0,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,\ +id=virtio-disk0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml new file mode 100644 index 0000000..dd8b00c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml @@ -0,0 +1,91 @@ +<domain type='kvm' id='56'> + <name>instance-00000092</name> + <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid> + <metadata> + <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0"> + <nova:package version="13.0.0"/> + <nova:name>emma</nova:name> + <nova:creationTime>2016-09-16 15:51:06</nova:creationTime> + <nova:flavor name="devstack"> + <nova:memory>14336</nova:memory> + <nova:disk>30</nova:disk> + <nova:swap>0</nova:swap> + <nova:ephemeral>0</nova:ephemeral> + <nova:vcpus>8</nova:vcpus> + </nova:flavor> + <nova:owner> + <nova:user uuid="ff95838725294b1896e887d4caee5e1a">tester</nova:user> + <nova:project uuid="f04e5e9722e441ae90bcc7f12722a0ac">test</nova:project> + </nova:owner> + <nova:root type="image" uuid="37ec79a5-9eb2-4df5-beee-a6942657d828"/> + </nova:instance> + </metadata> + <memory unit='KiB'>14680064</memory> + <currentMemory unit='KiB'>14680064</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='shared'/> + <allocation mode='immediate'/> + </memoryBacking> + <vcpu placement='static'>8</vcpu> + <cputune> + <shares>8192</shares> + </cputune> + <resource> + <partition>/machine</partition> + </resource> + <sysinfo type='smbios'> + <system> + <entry name='manufacturer'>OpenStack Foundation</entry> + <entry name='product'>OpenStack Nova</entry> + <entry name='version'>13.0.0</entry> + <entry name='serial'>0640ddd5-36c9-e211-a2f6-001e6789a0f1</entry> + <entry name='uuid'>126f2720-6f8e-45ab-a886-ec9277079a67</entry> + <entry name='family'>Virtual Machine</entry> + </system> + </sysinfo> + <os> + <type arch='x86_64' machine='pc-i440fx-wily'>hvm</type> + <boot dev='hd'/> + <smbios mode='sysinfo'/> + </os> + <features> + <acpi/> + <apic/> + </features> + <cpu mode='host-passthrough'> + <topology sockets='8' cores='1' threads='1'/> + </cpu> + <clock offset='utc'> + <timer name='pit' tickpolicy='delay'/> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk'/> + <backingStore type='file' index='1'> + <format type='raw'/> + <source file='/var/lib/nova/instances/_base/7205b893db62340da7d5246a23b66a52ccef9bd1'/> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <controller type='usb' index='0'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <memballoon model='virtio'> + <stats period='10'/> + <alias name='balloon0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args new file mode 100644 index 0000000..a41b264 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args @@ -0,0 +1,33 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name instance-00000092 \ +-S \ +-M pc-i440fx-wily \ +-cpu host \ +-m 14336 \ +-mem-prealloc \ +-smp 8,sockets=1,cores=8,threads=1 \ +-object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu,\ +share=yes,size=15032385536 \ +-numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \ +-uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ +-smbios 'type=1,manufacturer=OpenStack Foundation,product=OpenStack Nova,\ +version=13.0.0,serial=0640ddd5-36c9-e211-a2f6-001e6789a0f1,\ +uuid=126f2720-6f8e-45ab-a886-ec9277079a67,family=Virtual Machine' \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-instance-00000092/monitor.sock,server,nowait \ +-rtc base=utc,driftfix=slew \ +-no-kvm-pit-reinjection \ +-boot c \ +-usb \ +-drive file=/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk,\ +format=qcow2,if=none,id=drive-virtio-disk0,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,\ +id=virtio-disk0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml new file mode 100644 index 0000000..f2b1a2e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml @@ -0,0 +1,94 @@ + <domain type='kvm' id='56'> + <name>instance-00000092</name> + <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid> + <metadata> + <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0"> + <nova:package version="13.0.0"/> + <nova:name>emma</nova:name> + <nova:creationTime>2016-09-16 15:51:06</nova:creationTime> + <nova:flavor name="devstack"> + <nova:memory>14336</nova:memory> + <nova:disk>30</nova:disk> + <nova:swap>0</nova:swap> + <nova:ephemeral>0</nova:ephemeral> + <nova:vcpus>8</nova:vcpus> + </nova:flavor> + <nova:owner> + <nova:user uuid="ff95838725294b1896e887d4caee5e1a">tester</nova:user> + <nova:project uuid="f04e5e9722e441ae90bcc7f12722a0ac">test</nova:project> + </nova:owner> + <nova:root type="image" uuid="37ec79a5-9eb2-4df5-beee-a6942657d828"/> + </nova:instance> + </metadata> + <memory unit='KiB'>14680064</memory> + <currentMemory unit='KiB'>14680064</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='shared'/> + <allocation mode='immediate'/> + </memoryBacking> + <vcpu placement='static'>8</vcpu> + <cputune> + <shares>8192</shares> + </cputune> + <resource> + <partition>/machine</partition> + </resource> + <sysinfo type='smbios'> + <system> + <entry name='manufacturer'>OpenStack Foundation</entry> + <entry name='product'>OpenStack Nova</entry> + <entry name='version'>13.0.0</entry> + <entry name='serial'>0640ddd5-36c9-e211-a2f6-001e6789a0f1</entry> + <entry name='uuid'>126f2720-6f8e-45ab-a886-ec9277079a67</entry> + <entry name='family'>Virtual Machine</entry> + </system> + </sysinfo> + <os> + <type arch='x86_64' machine='pc-i440fx-wily'>hvm</type> + <boot dev='hd'/> + <smbios mode='sysinfo'/> + </os> + <features> + <acpi/> + <apic/> + </features> + <cpu mode='host-passthrough'> + <topology sockets='1' cores='8' threads='1'/> + <numa> + <cell id='0' cpus='0-7' memory='14680064' unit='KiB'/> + </numa> + </cpu> + <clock offset='utc'> + <timer name='pit' tickpolicy='delay'/> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk'/> + <backingStore type='file' index='1'> + <format type='raw'/> + <source file='/var/lib/nova/instances/_base/7205b893db62340da7d5246a23b66a52ccef9bd1'/> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <controller type='usb' index='0'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <memballoon model='virtio'> + <stats period='10'/> + <alias name='balloon0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> + </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args new file mode 100644 index 0000000..d12379c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args @@ -0,0 +1,36 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name instance-00000092 \ +-S \ +-M pc-i440fx-wily \ +-cpu host \ +-m 28672 \ +-mem-prealloc \ +-smp 20,sockets=1,cores=8,threads=1 \ +-object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu,\ +size=15032385536 \ +-numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \ +-object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu,\ +share=yes,size=15032385536 \ +-numa node,nodeid=1,cpus=8-15,memdev=ram-node1 \ +-uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ +-smbios 'type=1,manufacturer=OpenStack Foundation,product=OpenStack Nova,\ +version=13.0.0,serial=0640ddd5-36c9-e211-a2f6-001e6789a0f1,\ +uuid=126f2720-6f8e-45ab-a886-ec9277079a67,family=Virtual Machine' \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-instance-00000092/monitor.sock,server,nowait \ +-rtc base=utc,driftfix=slew \ +-no-kvm-pit-reinjection \ +-boot c \ +-usb \ +-drive file=/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk,\ +format=qcow2,if=none,id=drive-virtio-disk0,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,\ +id=virtio-disk0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.xml b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.xml new file mode 100644 index 0000000..625dc8a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.xml @@ -0,0 +1,95 @@ + <domain type='kvm' id='56'> + <name>instance-00000092</name> + <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid> + <metadata> + <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0"> + <nova:package version="13.0.0"/> + <nova:name>emma</nova:name> + <nova:creationTime>2016-09-16 15:51:06</nova:creationTime> + <nova:flavor name="devstack"> + <nova:memory>14336</nova:memory> + <nova:disk>30</nova:disk> + <nova:swap>0</nova:swap> + <nova:ephemeral>0</nova:ephemeral> + <nova:vcpus>20</nova:vcpus> + </nova:flavor> + <nova:owner> + <nova:user uuid="ff95838725294b1896e887d4caee5e1a">tester</nova:user> + <nova:project uuid="f04e5e9722e441ae90bcc7f12722a0ac">test</nova:project> + </nova:owner> + <nova:root type="image" uuid="37ec79a5-9eb2-4df5-beee-a6942657d828"/> + </nova:instance> + </metadata> + <memory unit='KiB'>14680064</memory> + <currentMemory unit='KiB'>14680064</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='private'/> + <allocation mode='immediate'/> + </memoryBacking> + <vcpu placement='static'>20</vcpu> + <cputune> + <shares>8192</shares> + </cputune> + <resource> + <partition>/machine</partition> + </resource> + <sysinfo type='smbios'> + <system> + <entry name='manufacturer'>OpenStack Foundation</entry> + <entry name='product'>OpenStack Nova</entry> + <entry name='version'>13.0.0</entry> + <entry name='serial'>0640ddd5-36c9-e211-a2f6-001e6789a0f1</entry> + <entry name='uuid'>126f2720-6f8e-45ab-a886-ec9277079a67</entry> + <entry name='family'>Virtual Machine</entry> + </system> + </sysinfo> + <os> + <type arch='x86_64' machine='pc-i440fx-wily'>hvm</type> + <boot dev='hd'/> + <smbios mode='sysinfo'/> + </os> + <features> + <acpi/> + <apic/> + </features> + <cpu mode='host-passthrough'> + <topology sockets='1' cores='8' threads='1'/> + <numa> + <cell id='0' cpus='0-7' memory='14680064' unit='KiB'/> + <cell id='1' cpus='8-15' memory='14680064' unit='KiB' memAccess='shared'/> + </numa> + </cpu> + <clock offset='utc'> + <timer name='pit' tickpolicy='delay'/> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk'/> + <backingStore type='file' index='1'> + <format type='raw'/> + <source file='/var/lib/nova/instances/_base/7205b893db62340da7d5246a23b66a52ccef9bd1'/> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <controller type='usb' index='0'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <memballoon model='virtio'> + <stats period='10'/> + <alias name='balloon0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> + </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args new file mode 100644 index 0000000..60a0ea9 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args @@ -0,0 +1,39 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name instance-00000092 \ +-S \ +-M pc-i440fx-wily \ +-cpu host \ +-m 43008 \ +-mem-prealloc \ +-smp 32,sockets=1,cores=24,threads=1 \ +-object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu,\ +share=yes,size=15032385536 \ +-numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \ +-object memory-backend-file,id=ram-node1,mem-path=/var/lib/libvirt/qemu,\ +share=yes,size=15032385536 \ +-numa node,nodeid=1,cpus=2-3,memdev=ram-node1 \ +-object memory-backend-file,id=ram-node2,mem-path=/var/lib/libvirt/qemu,\ +share=no,size=15032385536 \ +-numa node,nodeid=2,cpus=4-5,memdev=ram-node2 \ +-uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ +-smbios 'type=1,manufacturer=OpenStack Foundation,product=OpenStack Nova,\ +version=13.0.0,serial=0640ddd5-36c9-e211-a2f6-001e6789a0f1,\ +uuid=126f2720-6f8e-45ab-a886-ec9277079a67,family=Virtual Machine' \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-instance-00000092/monitor.sock,server,nowait \ +-rtc base=utc,driftfix=slew \ +-no-kvm-pit-reinjection \ +-boot c \ +-usb \ +-drive file=/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk,\ +format=qcow2,if=none,id=drive-virtio-disk0,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,\ +id=virtio-disk0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.xml b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.xml new file mode 100644 index 0000000..c170412 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.xml @@ -0,0 +1,96 @@ + <domain type='kvm' id='56'> + <name>instance-00000092</name> + <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid> + <metadata> + <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0"> + <nova:package version="13.0.0"/> + <nova:name>emma</nova:name> + <nova:creationTime>2016-09-16 15:51:06</nova:creationTime> + <nova:flavor name="devstack"> + <nova:memory>14336</nova:memory> + <nova:disk>30</nova:disk> + <nova:swap>0</nova:swap> + <nova:ephemeral>0</nova:ephemeral> + <nova:vcpus>24</nova:vcpus> + </nova:flavor> + <nova:owner> + <nova:user uuid="ff95838725294b1896e887d4caee5e1a">tester</nova:user> + <nova:project uuid="f04e5e9722e441ae90bcc7f12722a0ac">test</nova:project> + </nova:owner> + <nova:root type="image" uuid="37ec79a5-9eb2-4df5-beee-a6942657d828"/> + </nova:instance> + </metadata> + <memory unit='KiB'>14680064</memory> + <currentMemory unit='KiB'>14680064</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='shared'/> + <allocation mode='immediate'/> + </memoryBacking> + <vcpu placement='static'>32</vcpu> + <cputune> + <shares>8192</shares> + </cputune> + <resource> + <partition>/machine</partition> + </resource> + <sysinfo type='smbios'> + <system> + <entry name='manufacturer'>OpenStack Foundation</entry> + <entry name='product'>OpenStack Nova</entry> + <entry name='version'>13.0.0</entry> + <entry name='serial'>0640ddd5-36c9-e211-a2f6-001e6789a0f1</entry> + <entry name='uuid'>126f2720-6f8e-45ab-a886-ec9277079a67</entry> + <entry name='family'>Virtual Machine</entry> + </system> + </sysinfo> + <os> + <type arch='x86_64' machine='pc-i440fx-wily'>hvm</type> + <boot dev='hd'/> + <smbios mode='sysinfo'/> + </os> + <features> + <acpi/> + <apic/> + </features> + <cpu mode='host-passthrough'> + <topology sockets='1' cores='24' threads='1'/> + <numa> + <cell id='0' cpus='0-1' memory='14680064' unit='KiB'/> + <cell id='1' cpus='2-3' memory='14680064' unit='KiB' memAccess='shared'/> + <cell id='2' cpus='4-5' memory='14680064' unit='KiB' memAccess='private'/> + </numa> + </cpu> + <clock offset='utc'> + <timer name='pit' tickpolicy='delay'/> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk'/> + <backingStore type='file' index='1'> + <format type='raw'/> + <source file='/var/lib/nova/instances/_base/7205b893db62340da7d5246a23b66a52ccef9bd1'/> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <controller type='usb' index='0'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <memballoon model='virtio'> + <stats period='10'/> + <alias name='balloon0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> + </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml new file mode 100644 index 0000000..655eb8d --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>SomeDummyHugepagesGuest</name> + <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='shared'/> + <allocation mode='immediate'/> + </memoryBacking> + <vcpu placement='static'>2</vcpu> + <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</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml new file mode 100644 index 0000000..74f8a12 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>SomeDummyHugepagesGuest</name> + <uuid>ef1bdff4-27f3-4e85-a807-5fb4d58463cc</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <memoryBacking> + <source type="anonymous"/> + <access mode="private"/> + <allocation mode="ondemand"/> + </memoryBacking> + <vcpu placement='static'>2</vcpu> + <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</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 90d6aaf..e3d8499 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2217,6 +2217,48 @@ mymain(void) DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); + DO_TEST("fd-memory-numa-topology", QEMU_CAPS_RTC, QEMU_CAPS_NO_KVM_PIT, + QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_PCI_MULTIFUNCTION, + QEMU_CAPS_SPICE, QEMU_CAPS_CHARDEV_SPICEVMC, + QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_USB_REDIR, + QEMU_CAPS_DEVICE_PC_DIMM, + QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_FILE, + QEMU_CAPS_KVM, QEMU_CAPS_SMBIOS_TYPE, + QEMU_CAPS_VNC_WEBSOCKET, QEMU_CAPS_VNC); + DO_TEST("fd-memory-numa-topology2", QEMU_CAPS_RTC, QEMU_CAPS_NO_KVM_PIT, + QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_PCI_MULTIFUNCTION, + QEMU_CAPS_SPICE, QEMU_CAPS_CHARDEV_SPICEVMC, + QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_USB_REDIR, + QEMU_CAPS_DEVICE_PC_DIMM, + QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_FILE, + QEMU_CAPS_KVM, QEMU_CAPS_SMBIOS_TYPE, + QEMU_CAPS_VNC_WEBSOCKET, QEMU_CAPS_VNC); + DO_TEST("fd-memory-numa-topology3", QEMU_CAPS_RTC, QEMU_CAPS_NO_KVM_PIT, + QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_PCI_MULTIFUNCTION, + QEMU_CAPS_SPICE, QEMU_CAPS_CHARDEV_SPICEVMC, + QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_USB_REDIR, + QEMU_CAPS_DEVICE_PC_DIMM, + QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_FILE, + QEMU_CAPS_KVM, QEMU_CAPS_SMBIOS_TYPE, + QEMU_CAPS_VNC_WEBSOCKET, QEMU_CAPS_VNC); + + DO_TEST("fd-memory-no-numa-topology", QEMU_CAPS_RTC, QEMU_CAPS_NO_KVM_PIT, + QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4, + QEMU_CAPS_VIRTIO_SCSI, + QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_PCI_MULTIFUNCTION, + QEMU_CAPS_SPICE, QEMU_CAPS_CHARDEV_SPICEVMC, + QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_USB_REDIR, + QEMU_CAPS_DEVICE_PC_DIMM, + QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_FILE, + QEMU_CAPS_KVM, QEMU_CAPS_SMBIOS_TYPE, + QEMU_CAPS_VNC_WEBSOCKET, QEMU_CAPS_VNC); + qemuTestDriverFree(&driver); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -- 2.7.4 -------------------------------------------------------------- Intel Research and Development Ireland Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

On Tue, Nov 01, 2016 at 12:11:15PM +0000, Jaroslav Safka wrote:
This second change introduces support for preallocated shared file descriptor based memory backing. It allows vhost-user to be used without hugepages.
Also token memAccess in numa cell is used (if not present, default value from memoryBacking is used)
Used xml elements: <memoryBacking> <source type='file|anonymous'/> <access Mode='shared|private'/> <allocation mode='immediate|ondemand'/> </memoryBacking> --- src/qemu/qemu_command.c | 156 ++++++++++++++++----- src/qemu/qemu_command.h | 4 + .../qemuxml2argv-fd-memory-no-numa-topology.args | 33 +++++ .../qemuxml2argv-fd-memory-no-numa-topology.xml | 91 ++++++++++++ .../qemuxml2argv-fd-memory-numa-topology.args | 33 +++++ .../qemuxml2argv-fd-memory-numa-topology.xml | 94 +++++++++++++ .../qemuxml2argv-fd-memory-numa-topology2.args | 36 +++++ .../qemuxml2argv-fd-memory-numa-topology2.xml | 95 +++++++++++++ .../qemuxml2argv-fd-memory-numa-topology3.args | 39 ++++++ .../qemuxml2argv-fd-memory-numa-topology3.xml | 96 +++++++++++++ .../qemuxml2argv-memorybacking-set.xml | 32 +++++ .../qemuxml2argv-memorybacking-unset.xml | 32 +++++ tests/qemuxml2argvtest.c | 42 ++++++ 13 files changed, 750 insertions(+), 33 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology2.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology3.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b68da3d..7710864 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3283,15 +3283,11 @@ qemuBuildMemoryBackendStr(unsigned long long size, if (!(props = virJSONValueNewObject())) return -1;
- if (pagesize) { - if (qemuGetHupageMemPath(cfg, pagesize, &mem_path) < 0) - goto cleanup; - + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) { *backendType = "memory-backend-file";
if (virJSONValueObjectAdd(props, - "b:prealloc", true, - "s:mem-path", mem_path, + "s:mem-path", VIR_DOMAIN_MEMORY_DEFAULT_PATH, NULL) < 0) goto cleanup;
@@ -3307,18 +3303,61 @@ qemuBuildMemoryBackendStr(unsigned long long size, break;
case VIR_NUMA_MEM_ACCESS_DEFAULT: + if (def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED) { + if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0) + goto cleanup; + } + break; + case VIR_NUMA_MEM_ACCESS_LAST: break; } + + force = true; } else { - if (memAccess) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Shared memory mapping is supported " - "only with hugepages")); - goto cleanup; - } + if (pagesize) { + if (qemuGetHupageMemPath(cfg, pagesize, &mem_path) < 0) + goto cleanup;
- *backendType = "memory-backend-ram"; + *backendType = "memory-backend-file"; + + if (virJSONValueObjectAdd(props, + "b:prealloc", true, + "s:mem-path", mem_path, + NULL) < 0) + goto cleanup; + + switch (memAccess) { + case VIR_NUMA_MEM_ACCESS_SHARED: + if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0) + goto cleanup; + break; + + case VIR_NUMA_MEM_ACCESS_PRIVATE: + if (virJSONValueObjectAdd(props, "b:share", false, NULL) < 0) + goto cleanup; + break; + + case VIR_NUMA_MEM_ACCESS_DEFAULT: + if (def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED) { + if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0) + goto cleanup; + } + break; + + case VIR_NUMA_MEM_ACCESS_LAST: + break; + } + } else { + if (memAccess) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Shared memory mapping is supported " + "only with hugepages")); + goto cleanup; + } +
This message is not true anymore ^^.
+ *backendType = "memory-backend-ram"; + } }
if (virJSONValueObjectAdd(props, "U:size", size * 1024, NULL) < 0) @@ -7138,28 +7177,35 @@ qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg, const long system_page_size = virGetSystemPageSizeKB(); char *mem_path = NULL;
- /* - * No-op if hugepages were not requested. - */ - if (!def->mem.nhugepages) + if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) { + virCommandAddArgList(cmd, "-mem-prealloc", NULL); return 0; + }
- /* There is one special case: if user specified "huge" - * pages of regular system pages size. - * And there is nothing to do in this case. - */ - if (def->mem.hugepages[0].size == system_page_size) - return 0; + if (def->mem.nhugepages) {
- if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("hugepage backing not supported by '%s'"), - def->emulator); - return -1; - } + /* There is one special case: if user specified "huge" + * pages of regular system pages size. + * And there is nothing to do in this case. + */ + if (def->mem.hugepages[0].size == system_page_size) + return 0;
- if (qemuGetHupageMemPath(cfg, def->mem.hugepages[0].size, &mem_path) < 0) - return -1; + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("hugepage backing not supported by '%s'"), + def->emulator); + return -1; + } + + if (qemuGetHupageMemPath(cfg, def->mem.hugepages[0].size, &mem_path) < 0) + return -1; + } else { + /* + * No-op if hugepages or immediate allocation were not requested. + */ + return 0; + }
virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path", mem_path, NULL); VIR_FREE(mem_path); @@ -7195,8 +7241,9 @@ qemuBuildMemCommandLine(virCommandPtr cmd, * Add '-mem-path' (and '-mem-prealloc') parameter here only if * there is no numa node specified. */ - if (!virDomainNumaGetNodeCount(def->numa) && - qemuBuildMemPathStr(cfg, def, qemuCaps, cmd) < 0) + if ((!virDomainNumaGetNodeCount(def->numa) + || def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_IMMEDIATE) + && qemuBuildMemPathStr(cfg, def, qemuCaps, cmd) < 0)
Some calls are guarded by new conditions [1].
return -1;
if (def->mem.locked && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_REALTIME_MLOCK)) { @@ -9424,6 +9471,10 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, qemuBuildNumaArgStr(cfg, def, cmd, qemuCaps, nodeset) < 0) goto error;
+ if (!virDomainNumaGetNodeCount(def->numa) && + qemuBuildMemoryBackingCommandLine(def, cmd, qemuCaps) < 0) + goto error; +
This call is made if there is no NUMA for the machine [2]
if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, qemuCaps, nodeset) < 0) goto error;
@@ -9816,6 +9867,45 @@ qemuBuildChrDeviceStr(char **deviceStr,
return ret; } +int +qemuBuildMemoryBackingCommandLine(const virDomainDef *def, + virCommandPtr cmd, + virQEMUCapsPtr qemuCaps)
Indentation doesn't match here
+{ + int ret = -1; + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *alias = "ram"; + + if (def->mem.source != VIR_DOMAIN_MEMORY_SOURCE_FILE) { + ret = 0; + goto cleanup; + }
[1] and this function has another condition inside. It is *really* hard to read these patches. It is also partially because some whitespaces and all three patches having the same subject (almost). Even prefixing them would be enough
+ /* numa is disabled and mem source is file */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("File memory mapping is not supported " + "with this QEMU")); + goto cleanup; + } + + virCommandAddArg(cmd, "-object"); + virBufferAsprintf(&buf, "memory-backend-file,id=%s,mem-path=%s,", alias, VIR_DOMAIN_MEMORY_DEFAULT_PATH); + + if (def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED) + virBufferAsprintf(&buf, "%s", "share=yes,"); + + virBufferAsprintf(&buf, "size=%llu", virDomainDefGetMemoryInitial(def) / 1024); + virCommandAddArgBuffer(cmd, &buf); + + virCommandAddArg(cmd, "-numa"); + virCommandAddArgFormat(cmd, "node,memdev=%s", alias); +
[2] and you just add a numa node. I believe this will change guest ABI. You can say, though, that some of the options require there to be at least one NUMA node. Or document that this will automatically convert to having a NUMA node, but show that in the domain XML.
+ ret = 0; + cleanup: + + virBufferFreeAndReset(&buf); + return ret; +}
virJSONValuePtr diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index a793fb6..c0ecd62 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -183,6 +183,10 @@ bool qemuCheckCCWS390AddressSupport(const virDomainDef *def, virDomainDeviceInfo info, virQEMUCapsPtr qemuCaps, const char *devicename); +int +qemuBuildMemoryBackingCommandLine(const virDomainDef *def, + virCommandPtr cmd, + virQEMUCapsPtr qemuCaps);
virJSONValuePtr qemuBuildHotpluggableCPUProps(const virDomainVcpuDef *vcpu) ATTRIBUTE_NONNULL(1); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args new file mode 100644 index 0000000..1563693 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.args @@ -0,0 +1,33 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name instance-00000092 \ +-S \ +-M pc-i440fx-wily \ +-cpu host \ +-m 14336 \ +-mem-prealloc \ +-smp 8,sockets=8,cores=1,threads=1 \ +-object memory-backend-file,id=ram,mem-path=/var/lib/libvirt/qemu,share=yes,\ +size=14336 \ +-numa node,memdev=ram \ +-uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ +-smbios 'type=1,manufacturer=OpenStack Foundation,product=OpenStack Nova,\ +version=13.0.0,serial=0640ddd5-36c9-e211-a2f6-001e6789a0f1,\ +uuid=126f2720-6f8e-45ab-a886-ec9277079a67,family=Virtual Machine' \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-instance-00000092/monitor.sock,server,nowait \ +-rtc base=utc,driftfix=slew \ +-no-kvm-pit-reinjection \ +-boot c \ +-usb \ +-drive file=/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk,\ +format=qcow2,if=none,id=drive-virtio-disk0,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,\ +id=virtio-disk0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml new file mode 100644 index 0000000..dd8b00c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-no-numa-topology.xml @@ -0,0 +1,91 @@ +<domain type='kvm' id='56'> + <name>instance-00000092</name> + <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid> + <metadata> + <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0"> + <nova:package version="13.0.0"/> + <nova:name>emma</nova:name> + <nova:creationTime>2016-09-16 15:51:06</nova:creationTime> + <nova:flavor name="devstack"> + <nova:memory>14336</nova:memory> + <nova:disk>30</nova:disk> + <nova:swap>0</nova:swap> + <nova:ephemeral>0</nova:ephemeral> + <nova:vcpus>8</nova:vcpus> + </nova:flavor> + <nova:owner> + <nova:user uuid="ff95838725294b1896e887d4caee5e1a">tester</nova:user> + <nova:project uuid="f04e5e9722e441ae90bcc7f12722a0ac">test</nova:project> + </nova:owner> + <nova:root type="image" uuid="37ec79a5-9eb2-4df5-beee-a6942657d828"/> + </nova:instance> + </metadata> + <memory unit='KiB'>14680064</memory> + <currentMemory unit='KiB'>14680064</currentMemory> + <memoryBacking> + <source type='file'/> + <access mode='shared'/> + <allocation mode='immediate'/> + </memoryBacking> + <vcpu placement='static'>8</vcpu> + <cputune> + <shares>8192</shares> + </cputune> + <resource> + <partition>/machine</partition> + </resource> + <sysinfo type='smbios'> + <system> + <entry name='manufacturer'>OpenStack Foundation</entry> + <entry name='product'>OpenStack Nova</entry> + <entry name='version'>13.0.0</entry> + <entry name='serial'>0640ddd5-36c9-e211-a2f6-001e6789a0f1</entry> + <entry name='uuid'>126f2720-6f8e-45ab-a886-ec9277079a67</entry> + <entry name='family'>Virtual Machine</entry> + </system> + </sysinfo> + <os> + <type arch='x86_64' machine='pc-i440fx-wily'>hvm</type> + <boot dev='hd'/> + <smbios mode='sysinfo'/> + </os> + <features> + <acpi/> + <apic/> + </features> + <cpu mode='host-passthrough'> + <topology sockets='8' cores='1' threads='1'/> + </cpu> + <clock offset='utc'> + <timer name='pit' tickpolicy='delay'/> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk'/> + <backingStore type='file' index='1'> + <format type='raw'/> + <source file='/var/lib/nova/instances/_base/7205b893db62340da7d5246a23b66a52ccef9bd1'/> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <controller type='usb' index='0'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <memballoon model='virtio'> + <stats period='10'/> + <alias name='balloon0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args new file mode 100644 index 0000000..a41b264 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.args @@ -0,0 +1,33 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name instance-00000092 \ +-S \ +-M pc-i440fx-wily \ +-cpu host \ +-m 14336 \ +-mem-prealloc \ +-smp 8,sockets=1,cores=8,threads=1 \ +-object memory-backend-file,id=ram-node0,mem-path=/var/lib/libvirt/qemu,\ +share=yes,size=15032385536 \ +-numa node,nodeid=0,cpus=0-7,memdev=ram-node0 \ +-uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ +-smbios 'type=1,manufacturer=OpenStack Foundation,product=OpenStack Nova,\ +version=13.0.0,serial=0640ddd5-36c9-e211-a2f6-001e6789a0f1,\ +uuid=126f2720-6f8e-45ab-a886-ec9277079a67,family=Virtual Machine' \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-instance-00000092/monitor.sock,server,nowait \ +-rtc base=utc,driftfix=slew \ +-no-kvm-pit-reinjection \ +-boot c \ +-usb \ +-drive file=/var/lib/nova/instances/126f2720-6f8e-45ab-a886-ec9277079a67/disk,\ +format=qcow2,if=none,id=drive-virtio-disk0,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,\ +id=virtio-disk0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml new file mode 100644 index 0000000..f2b1a2e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fd-memory-numa-topology.xml @@ -0,0 +1,94 @@ + <domain type='kvm' id='56'> + <name>instance-00000092</name> + <uuid>126f2720-6f8e-45ab-a886-ec9277079a67</uuid> + <metadata> + <nova:instance xmlns:nova="http://openstack.org/xmlns/libvirt/nova/1.0"> + <nova:package version="13.0.0"/> + <nova:name>emma</nova:name> + <nova:creationTime>2016-09-16 15:51:06</nova:creationTime> + <nova:flavor name="devstack"> + <nova:memory>14336</nova:memory> + <nova:disk>30</nova:disk> + <nova:swap>0</nova:swap> + <nova:ephemeral>0</nova:ephemeral> + <nova:vcpus>8</nova:vcpus> + </nova:flavor> + <nova:owner> + <nova:user uuid="ff95838725294b1896e887d4caee5e1a">tester</nova:user> + <nova:project uuid="f04e5e9722e441ae90bcc7f12722a0ac">test</nova:project> + </nova:owner> + <nova:root type="image" uuid="37ec79a5-9eb2-4df5-beee-a6942657d828"/> + </nova:instance> + </metadata>
Pointless metadata ^^. And more. If you want to test more things, then note that in the name, but please make the file test only what matters for the end goal.

Add html documentation for memoryBacking element. --- docs/formatdomain.html.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index c70377b..ed15eb5 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -903,6 +903,9 @@ </hugepages> <nosharepages/> <locked/> + <source type='file|anonymous'/> + <access mode='shared|private'> + <allocation mode='immediate|ondemand'/> </memoryBacking> ... </domain> @@ -942,6 +945,13 @@ most of the host's memory). Doing so may be dangerous to both the domain and the host itself since the host's kernel may run out of memory. <span class="since">Since 1.0.6</span></dd> + <dt><code>source</code></dt> + <dd>If the option "file" is selected, then token "mem-path=/var/lib/libvirt/qemu" will be added to object argument.</dd> + <dt><code>access</code></dt> + <dd>Specify if memory is shared or private. This can be overridden by numa cell element memAccess. + If share is selected then token "share=yes" will be added to object memory-backend-file.</dd> + <dt><code>allocation</code></dt> + <dd>Immediate - preallocate the memory immediately</dd> </dl> -- 2.7.4 -------------------------------------------------------------- Intel Research and Development Ireland Limited Registered in Ireland Registered Office: Collinstown Industrial Park, Leixlip, County Kildare Registered Number: 308263 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

On Tue, Nov 01, 2016 at 12:11:16PM +0000, Jaroslav Safka wrote:
Add html documentation for memoryBacking element.
We usually merge documentation with the conf changes.
--- docs/formatdomain.html.in | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index c70377b..ed15eb5 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -903,6 +903,9 @@ </hugepages> <nosharepages/> <locked/> + <source type='file|anonymous'/> + <access mode='shared|private'> + <allocation mode='immediate|ondemand'/> </memoryBacking> ... </domain> @@ -942,6 +945,13 @@ most of the host's memory). Doing so may be dangerous to both the domain and the host itself since the host's kernel may run out of memory. <span class="since">Since 1.0.6</span></dd> + <dt><code>source</code></dt> + <dd>If the option "file" is selected, then token "mem-path=/var/lib/libvirt/qemu" will be added to object argument.</dd>
You should say it is the <code>type</code> attribute. Also talking about tokens being added to object argument makes no sense for the reader. And I'm not talking about hypervisors other than QEMU where it doesn't make sense even to developers.
+ <dt><code>access</code></dt> + <dd>Specify if memory is shared or private. This can be overridden by numa cell element memAccess.
overridden *per node*. We enclose element and attribute names inside <code/> so that others can see that you are referring to something.
+ If share is selected then token "share=yes" will be added to object memory-backend-file.</dd>
Again, this makes no sense in high-lieve documentation.
+ <dt><code>allocation</code></dt> + <dd>Immediate - preallocate the memory immediately</dd>
^^ no comment.
participants (2)
-
Jaroslav Safka
-
Martin Kletzander