mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
qemu: Implement memoryBacking/discard
https://bugzilla.redhat.com/show_bug.cgi?id=1480668 QEMU has this new feature memory-backend-file.discard-data=yes which is a nifty optimization. Basically, when qemu is quitting or on memory hotplug it calls munmap() and close() on the file that is backing the memory. However, this does not mean kernel won't stop touching that part of memory. It still might. With this feature enabled we tell kernel: "we don't need this memory nor data stored in it". This makes kernel drop the memory immediately without trying to sync memory with the mapped file. Unfortunately, this cannot be turned on by default because we can't be sure when users really don't care about what happens to data after qemu dies. So it has to be opt-in. As usual, there are three places where one can configure memory attributes. This patch adds the feature to all of them. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
2300c92fe0
commit
2c4affd57e
@ -3029,6 +3029,7 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
|
|||||||
unsigned long long pagesize = mem->pagesize;
|
unsigned long long pagesize = mem->pagesize;
|
||||||
bool needHugepage = !!pagesize;
|
bool needHugepage = !!pagesize;
|
||||||
bool useHugepage = !!pagesize;
|
bool useHugepage = !!pagesize;
|
||||||
|
int discard = mem->discard;
|
||||||
|
|
||||||
/* The difference between @needHugepage and @useHugepage is that the latter
|
/* The difference between @needHugepage and @useHugepage is that the latter
|
||||||
* is true whenever huge page is defined for the current memory cell.
|
* is true whenever huge page is defined for the current memory cell.
|
||||||
@ -3039,8 +3040,7 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
|
|||||||
*backendProps = NULL;
|
*backendProps = NULL;
|
||||||
*backendType = NULL;
|
*backendType = NULL;
|
||||||
|
|
||||||
if (memAccess == VIR_DOMAIN_MEMORY_ACCESS_DEFAULT &&
|
if (mem->targetNode >= 0) {
|
||||||
mem->targetNode >= 0) {
|
|
||||||
/* memory devices could provide a invalid guest node */
|
/* memory devices could provide a invalid guest node */
|
||||||
if (mem->targetNode >= virDomainNumaGetNodeCount(def->numa)) {
|
if (mem->targetNode >= virDomainNumaGetNodeCount(def->numa)) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
@ -3050,12 +3050,19 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memAccess = virDomainNumaGetNodeMemoryAccessMode(def->numa, mem->targetNode);
|
if (memAccess == VIR_DOMAIN_MEMORY_ACCESS_DEFAULT)
|
||||||
|
memAccess = virDomainNumaGetNodeMemoryAccessMode(def->numa, mem->targetNode);
|
||||||
|
|
||||||
|
if (discard == VIR_TRISTATE_BOOL_ABSENT)
|
||||||
|
discard = virDomainNumaGetNodeDiscard(def->numa, mem->targetNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memAccess == VIR_DOMAIN_MEMORY_ACCESS_DEFAULT)
|
if (memAccess == VIR_DOMAIN_MEMORY_ACCESS_DEFAULT)
|
||||||
memAccess = def->mem.access;
|
memAccess = def->mem.access;
|
||||||
|
|
||||||
|
if (discard == VIR_TRISTATE_BOOL_ABSENT)
|
||||||
|
discard = def->mem.discard;
|
||||||
|
|
||||||
if (virDomainNumatuneGetMode(def->numa, mem->targetNode, &mode) < 0 &&
|
if (virDomainNumatuneGetMode(def->numa, mem->targetNode, &mode) < 0 &&
|
||||||
virDomainNumatuneGetMode(def->numa, -1, &mode) < 0)
|
virDomainNumatuneGetMode(def->numa, -1, &mode) < 0)
|
||||||
mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
||||||
@ -3143,6 +3150,20 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
|
|||||||
NULL) < 0)
|
NULL) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!mem->nvdimmPath &&
|
||||||
|
discard == VIR_TRISTATE_BOOL_YES) {
|
||||||
|
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD)) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("this QEMU doesn't support memory discard"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectAdd(props,
|
||||||
|
"B:discard-data", true,
|
||||||
|
NULL) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
switch (memAccess) {
|
switch (memAccess) {
|
||||||
case VIR_DOMAIN_MEMORY_ACCESS_SHARED:
|
case VIR_DOMAIN_MEMORY_ACCESS_SHARED:
|
||||||
if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0)
|
if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0)
|
||||||
|
@ -11,20 +11,20 @@ QEMU_AUDIO_DRV=none \
|
|||||||
-m 4096 \
|
-m 4096 \
|
||||||
-smp 4,sockets=4,cores=1,threads=1 \
|
-smp 4,sockets=4,cores=1,threads=1 \
|
||||||
-object memory-backend-file,id=ram-node0,prealloc=yes,\
|
-object memory-backend-file,id=ram-node0,prealloc=yes,\
|
||||||
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
|
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,discard-data=yes,\
|
||||||
host-nodes=0-3,policy=bind \
|
size=1073741824,host-nodes=0-3,policy=bind \
|
||||||
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
|
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
|
||||||
-object memory-backend-file,id=ram-node1,prealloc=yes,\
|
-object memory-backend-file,id=ram-node1,prealloc=yes,\
|
||||||
mem-path=/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
|
mem-path=/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
|
||||||
host-nodes=0-3,policy=bind \
|
host-nodes=0-3,policy=bind \
|
||||||
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
|
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
|
||||||
-object memory-backend-file,id=ram-node2,prealloc=yes,\
|
-object memory-backend-file,id=ram-node2,prealloc=yes,\
|
||||||
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
|
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,discard-data=yes,\
|
||||||
host-nodes=0-3,policy=bind \
|
size=1073741824,host-nodes=0-3,policy=bind \
|
||||||
-numa node,nodeid=2,cpus=2,memdev=ram-node2 \
|
-numa node,nodeid=2,cpus=2,memdev=ram-node2 \
|
||||||
-object memory-backend-file,id=ram-node3,prealloc=yes,\
|
-object memory-backend-file,id=ram-node3,prealloc=yes,\
|
||||||
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
|
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,discard-data=yes,\
|
||||||
host-nodes=3,policy=bind \
|
size=1073741824,host-nodes=3,policy=bind \
|
||||||
-numa node,nodeid=3,cpus=3,memdev=ram-node3 \
|
-numa node,nodeid=3,cpus=3,memdev=ram-node3 \
|
||||||
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
|
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
|
||||||
-display none \
|
-display none \
|
||||||
|
@ -13,7 +13,8 @@ QEMU_AUDIO_DRV=none \
|
|||||||
-object memory-backend-ram,id=ram-node0,size=268435456 \
|
-object memory-backend-ram,id=ram-node0,size=268435456 \
|
||||||
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
|
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
|
||||||
-object memory-backend-file,id=ram-node1,prealloc=yes,\
|
-object memory-backend-file,id=ram-node1,prealloc=yes,\
|
||||||
mem-path=/dev/hugepages1G/libvirt/qemu/-1-SomeDummyHugepagesGu,size=805306368 \
|
mem-path=/dev/hugepages1G/libvirt/qemu/-1-SomeDummyHugepagesGu,\
|
||||||
|
discard-data=yes,size=805306368 \
|
||||||
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
|
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
|
||||||
-uuid ef1bdff4-27f3-4e85-a807-5fb4d58463cc \
|
-uuid ef1bdff4-27f3-4e85-a807-5fb4d58463cc \
|
||||||
-display none \
|
-display none \
|
||||||
|
@ -18,7 +18,8 @@ mem-path=/dev/hugepages1G/libvirt/qemu/-1-fedora,size=1073741824,\
|
|||||||
host-nodes=1-3,policy=bind \
|
host-nodes=1-3,policy=bind \
|
||||||
-device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \
|
-device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \
|
||||||
-object memory-backend-file,id=memdimm1,prealloc=yes,\
|
-object memory-backend-file,id=memdimm1,prealloc=yes,\
|
||||||
mem-path=/dev/hugepages2M/libvirt/qemu/-1-fedora,share=no,size=536870912 \
|
mem-path=/dev/hugepages2M/libvirt/qemu/-1-fedora,discard-data=yes,share=no,\
|
||||||
|
size=536870912 \
|
||||||
-device pc-dimm,node=0,memdev=memdimm1,id=dimm1,slot=1 \
|
-device pc-dimm,node=0,memdev=memdimm1,id=dimm1,slot=1 \
|
||||||
-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
|
-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
|
||||||
-display none \
|
-display none \
|
||||||
|
@ -919,11 +919,13 @@ mymain(void)
|
|||||||
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
||||||
DO_TEST("hugepages-pages",
|
DO_TEST("hugepages-pages",
|
||||||
QEMU_CAPS_OBJECT_MEMORY_RAM,
|
QEMU_CAPS_OBJECT_MEMORY_RAM,
|
||||||
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
QEMU_CAPS_OBJECT_MEMORY_FILE,
|
||||||
|
QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD);
|
||||||
DO_TEST("hugepages-pages2", QEMU_CAPS_OBJECT_MEMORY_RAM,
|
DO_TEST("hugepages-pages2", QEMU_CAPS_OBJECT_MEMORY_RAM,
|
||||||
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
||||||
DO_TEST("hugepages-pages3", QEMU_CAPS_OBJECT_MEMORY_RAM,
|
DO_TEST("hugepages-pages3", QEMU_CAPS_OBJECT_MEMORY_RAM,
|
||||||
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
QEMU_CAPS_OBJECT_MEMORY_FILE,
|
||||||
|
QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD);
|
||||||
DO_TEST("hugepages-shared",
|
DO_TEST("hugepages-shared",
|
||||||
QEMU_CAPS_OBJECT_MEMORY_RAM,
|
QEMU_CAPS_OBJECT_MEMORY_RAM,
|
||||||
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
QEMU_CAPS_OBJECT_MEMORY_FILE);
|
||||||
@ -933,7 +935,8 @@ mymain(void)
|
|||||||
DO_TEST("hugepages-pages5", NONE);
|
DO_TEST("hugepages-pages5", NONE);
|
||||||
DO_TEST("hugepages-pages6", NONE);
|
DO_TEST("hugepages-pages6", NONE);
|
||||||
DO_TEST("hugepages-pages7",
|
DO_TEST("hugepages-pages7",
|
||||||
QEMU_CAPS_DEVICE_PC_DIMM, QEMU_CAPS_OBJECT_MEMORY_FILE);
|
QEMU_CAPS_DEVICE_PC_DIMM, QEMU_CAPS_OBJECT_MEMORY_FILE,
|
||||||
|
QEMU_CAPS_OBJECT_MEMORY_FILE_DISCARD);
|
||||||
DO_TEST("hugepages-memaccess", QEMU_CAPS_OBJECT_MEMORY_FILE,
|
DO_TEST("hugepages-memaccess", QEMU_CAPS_OBJECT_MEMORY_FILE,
|
||||||
QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_DEVICE_PC_DIMM,
|
QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_DEVICE_PC_DIMM,
|
||||||
QEMU_CAPS_NUMA);
|
QEMU_CAPS_NUMA);
|
||||||
|
Loading…
Reference in New Issue
Block a user