mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
conf: Add new xml elements for file memorybacking support
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>
This commit is contained in:
parent
48d9e6cdcc
commit
bc6d3121a4
@ -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>
|
||||
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
goto error;
|
||||
def->mem.nhugepages++;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
VIR_FREE(nodes);
|
||||
} else {
|
||||
if ((node = virXPathNode("./memoryBacking/hugepages", ctxt))) {
|
||||
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;
|
||||
|
||||
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 {
|
||||
/* 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");
|
||||
}
|
||||
|
@ -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 */
|
||||
|
24
tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml
Normal file
24
tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml
Normal file
@ -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>
|
24
tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml
Normal file
24
tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml
Normal file
@ -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>
|
@ -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>
|
@ -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>
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user