diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 81a9811d14..11ad77f145 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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) diff --git a/tests/qemuxml2argvdata/hugepages-pages.args b/tests/qemuxml2argvdata/hugepages-pages.args index 7ece0272a0..b52cd581d5 100644 --- a/tests/qemuxml2argvdata/hugepages-pages.args +++ b/tests/qemuxml2argvdata/hugepages-pages.args @@ -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 \ diff --git a/tests/qemuxml2argvdata/hugepages-pages3.args b/tests/qemuxml2argvdata/hugepages-pages3.args index 2fc701ca22..d55265cdd8 100644 --- a/tests/qemuxml2argvdata/hugepages-pages3.args +++ b/tests/qemuxml2argvdata/hugepages-pages3.args @@ -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 \ diff --git a/tests/qemuxml2argvdata/hugepages-pages7.args b/tests/qemuxml2argvdata/hugepages-pages7.args index 1cb598d692..02a98026eb 100644 --- a/tests/qemuxml2argvdata/hugepages-pages7.args +++ b/tests/qemuxml2argvdata/hugepages-pages7.args @@ -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 \ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 756ca7a77f..d4d64b0d21 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -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);