This part introduces new xml elements for file based memorybacking support and their parsing. (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/formatdomain.html.in | 9 ++ docs/schemas/domaincommon.rng | 30 +++++ src/conf/domain_conf.c | 133 ++++++++++++++++----- src/conf/domain_conf.h | 22 ++++ .../qemuxml2argv-memorybacking-set.xml | 24 ++++ .../qemuxml2argv-memorybacking-unset.xml | 24 ++++ .../qemuxml2xmlout-memorybacking-set.xml | 32 +++++ .../qemuxml2xmlout-memorybacking-unset.xml | 32 +++++ tests/qemuxml2xmltest.c | 3 + 9 files changed, 276 insertions(+), 33 deletions(-) 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 diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 77d8e71..0a115f5 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,12 @@ 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>In this attribute you can switch to file memorybacking or keep default anonymous.</dd> + <dt><code>access</code></dt> + <dd>Specify if memory is shared or private. This can be overridden per numa node by <code>memAccess</code></dd> + <dt><code>allocation</code></dt> + <dd>Specify when allocate the memory</dd> </dl> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index cc6e0d0..d715bff 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -565,6 +565,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 877a0bf..e47b87f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -837,6 +837,16 @@ 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(virDomainMemoryAllocation, VIR_DOMAIN_MEMORY_ALLOCATION_LAST, + "none", + "immediate", + "ondemand") + VIR_ENUM_IMPL(virDomainLoader, VIR_DOMAIN_LOADER_TYPE_LAST, "rom", @@ -16594,48 +16604,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; @@ -23728,7 +23783,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) @@ -23737,6 +23794,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 4d830c5..2615630 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -586,6 +586,22 @@ typedef enum { VIR_DOMAIN_DISK_MIRROR_STATE_LAST } virDomainDiskMirrorState; +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_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 { @@ -2130,6 +2146,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; @@ -3115,6 +3135,8 @@ VIR_ENUM_DECL(virDomainTPMModel) VIR_ENUM_DECL(virDomainTPMBackend) VIR_ENUM_DECL(virDomainMemoryModel) VIR_ENUM_DECL(virDomainMemoryBackingModel) +VIR_ENUM_DECL(virDomainMemorySource) +VIR_ENUM_DECL(virDomainMemoryAllocation) VIR_ENUM_DECL(virDomainIOMMUModel) VIR_ENUM_DECL(virDomainShmemModel) /* from libvirt.h */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml new file mode 100644 index 0000000..e23bc36 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml @@ -0,0 +1,24 @@ +<domain type='qemu'> + <name>SomeDummyGuest</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> + <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..6f50765 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml @@ -0,0 +1,24 @@ +<domain type='qemu'> + <name>SomeDummyGuest</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> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml new file mode 100644 index 0000000..fb07472 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>SomeDummyGuest</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> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </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..ac2a278 --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml @@ -0,0 +1,32 @@ +<domain type='qemu'> + <name>SomeDummyGuest</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> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </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 4f3b09a..0702f58 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1042,6 +1042,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. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list