提交 2c4affd5 编写于 作者: M Michal Privoznik

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: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 2300c92f
......@@ -3029,6 +3029,7 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
unsigned long long pagesize = mem->pagesize;
bool needHugepage = !!pagesize;
bool useHugepage = !!pagesize;
int discard = mem->discard;
/* The difference between @needHugepage and @useHugepage is that the latter
* is true whenever huge page is defined for the current memory cell.
......@@ -3039,8 +3040,7 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
*backendProps = NULL;
*backendType = NULL;
if (memAccess == VIR_DOMAIN_MEMORY_ACCESS_DEFAULT &&
mem->targetNode >= 0) {
if (mem->targetNode >= 0) {
/* memory devices could provide a invalid guest node */
if (mem->targetNode >= virDomainNumaGetNodeCount(def->numa)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
......@@ -3050,12 +3050,19 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
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)
memAccess = def->mem.access;
if (discard == VIR_TRISTATE_BOOL_ABSENT)
discard = def->mem.discard;
if (virDomainNumatuneGetMode(def->numa, mem->targetNode, &mode) < 0 &&
virDomainNumatuneGetMode(def->numa, -1, &mode) < 0)
mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
......@@ -3143,6 +3150,20 @@ qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
NULL) < 0)
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) {
case VIR_DOMAIN_MEMORY_ACCESS_SHARED:
if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0)
......
......@@ -11,20 +11,20 @@ QEMU_AUDIO_DRV=none \
-m 4096 \
-smp 4,sockets=4,cores=1,threads=1 \
-object memory-backend-file,id=ram-node0,prealloc=yes,\
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
host-nodes=0-3,policy=bind \
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,discard-data=yes,\
size=1073741824,host-nodes=0-3,policy=bind \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-object memory-backend-file,id=ram-node1,prealloc=yes,\
mem-path=/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
host-nodes=0-3,policy=bind \
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
-object memory-backend-file,id=ram-node2,prealloc=yes,\
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
host-nodes=0-3,policy=bind \
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,discard-data=yes,\
size=1073741824,host-nodes=0-3,policy=bind \
-numa node,nodeid=2,cpus=2,memdev=ram-node2 \
-object memory-backend-file,id=ram-node3,prealloc=yes,\
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,size=1073741824,\
host-nodes=3,policy=bind \
mem-path=/dev/hugepages1G/libvirt/qemu/-1-QEMUGuest1,discard-data=yes,\
size=1073741824,host-nodes=3,policy=bind \
-numa node,nodeid=3,cpus=3,memdev=ram-node3 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
-display none \
......
......@@ -13,7 +13,8 @@ QEMU_AUDIO_DRV=none \
-object memory-backend-ram,id=ram-node0,size=268435456 \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-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 \
-uuid ef1bdff4-27f3-4e85-a807-5fb4d58463cc \
-display none \
......
......@@ -18,7 +18,8 @@ mem-path=/dev/hugepages1G/libvirt/qemu/-1-fedora,size=1073741824,\
host-nodes=1-3,policy=bind \
-device pc-dimm,node=0,memdev=memdimm0,id=dimm0,slot=0 \
-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 \
-uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \
-display none \
......
......@@ -919,11 +919,13 @@ mymain(void)
QEMU_CAPS_OBJECT_MEMORY_FILE);
DO_TEST("hugepages-pages",
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,
QEMU_CAPS_OBJECT_MEMORY_FILE);
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",
QEMU_CAPS_OBJECT_MEMORY_RAM,
QEMU_CAPS_OBJECT_MEMORY_FILE);
......@@ -933,7 +935,8 @@ mymain(void)
DO_TEST("hugepages-pages5", NONE);
DO_TEST("hugepages-pages6", NONE);
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,
QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_DEVICE_PC_DIMM,
QEMU_CAPS_NUMA);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册