QEMU introduced command line "-mem-merge=on|off" (defaults to on) to enable/disable the memory merge (KSM) at guest startup. This exposes it by new XML: <memoryBacking> <nosharepages/> </memoryBacking> The XML tag is same with what we used internally for old RHEL. --- docs/formatdomain.html.in | 13 +++++++--- docs/schemas/domaincommon.rng | 5 ++++ src/conf/domain_conf.c | 20 ++++++++++----- src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 4 +++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 11 ++++++++ .../qemuxml2argv-nosharepages.args | 4 +++ .../qemuxml2argvdata/qemuxml2argv-nosharepages.xml | 29 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmltest.c | 1 + 11 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 0cc56d9..4350610 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -558,6 +558,7 @@ ... <memoryBacking> <hugepages/> + <nosharepages/> </memoryBacking> ... </domain> @@ -565,10 +566,14 @@ <dl> <dt><code>memoryBacking</code></dt> - <dd>The optional <code>memoryBacking</code> element, may have an - <code>hugepages</code> element set within it. This tells the - hypervisor that the guest should have its memory allocated using - hugepages instead of the normal native page size.</dd> + <dd>The optional <code>memoryBacking</code> element has two + optional elements. The element <code>hugepages</code> tells + the hypervisor that the guest should have its memory allocated + using hugepages instead of the normal native page size. And the + optional element <code>nosharepages</code> tells the hypervisor + that share pages (memory merge, KSM) should be disabled on guest + startup. + </dd> </dl> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 468c49c..a1e25ca 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -495,6 +495,11 @@ <empty/> </element> </optional> + <optional> + <element name="nosharepages"> + <empty/> + </element> + </optional> </element> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 548368e..231cc41 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10018,6 +10018,9 @@ virDomainDefParseXML(xmlDocPtr xml, if ((node = virXPathNode("./memoryBacking/hugepages", ctxt))) def->mem.hugepage_backed = true; + if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt))) + def->mem.nosharepages = true; + /* Extract blkio cgroup tunables */ if (virXPathUInt("string(./blkiotune/weight)", ctxt, &def->blkio.weight) < 0) @@ -15263,12 +15266,17 @@ virDomainDefFormatInternal(virDomainDefPtr def, def->mem.swap_hard_limit) virBufferAddLit(buf, " </memtune>\n"); - if (def->mem.hugepage_backed) { - virBufferStrcat(buf, - " <memoryBacking>\n", - " <hugepages/>\n", - " </memoryBacking>\n", NULL); - } + if (def->mem.hugepage_backed || def->mem.nosharepages) + virBufferAddLit(buf, " <memoryBacking>\n"); + + if (def->mem.hugepage_backed) + virBufferAddLit(buf, " <hugepages/>\n"); + + if (def->mem.nosharepages) + virBufferAddLit(buf, " <nosharepages/>\n"); + + if (def->mem.hugepage_backed || def->mem.nosharepages) + virBufferAddLit(buf, " </memoryBacking>\n"); virBufferAddLit(buf, " <vcpu"); virBufferAsprintf(buf, " placement='%s'", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f1f01fa..0ba72d5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1811,6 +1811,7 @@ struct _virDomainDef { unsigned long long max_balloon; /* in kibibytes */ unsigned long long cur_balloon; /* in kibibytes */ bool hugepage_backed; + bool nosharepages; int dump_core; /* enum virDomainMemDump */ unsigned long long hard_limit; /* in kibibytes */ unsigned long long soft_limit; /* in kibibytes */ diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d10c8aa..e5d89f9 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -220,6 +220,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "machine-usb-opt", "tpm-passthrough", "tpm-tis", + "mem-merge", ); struct _virQEMUCaps { @@ -1082,6 +1083,9 @@ virQEMUCapsComputeCmdFlags(const char *help, if (strstr(help, "-machine")) virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT); + if (strstr(help, "-mem-merge")) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_MEM_MERGE); + /* USB option is supported v1.3.0 onwards */ if (qemuCaps->version >= 1003000) virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 4e76799..55ffd35 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -178,6 +178,7 @@ enum virQEMUCapsFlags { QEMU_CAPS_MACHINE_USB_OPT = 137, /* -machine xxx,usb=on/off */ QEMU_CAPS_DEVICE_TPM_PASSTHROUGH = 138, /* -tpmdev passthrough */ QEMU_CAPS_DEVICE_TPM_TIS = 139, /* -device tpm_tis */ + QEMU_CAPS_MEM_MERGE = 140, /* Is -mem-merge available? */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 009d42d..bb0ccff 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5993,6 +5993,17 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, smp); VIR_FREE(smp); + if (def->mem.nosharepages) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_MERGE)) { + virCommandAddArg(cmd, "-mem-merge=off"); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("the QEMU binary %s does not support to " + "disable shared memory"), emulator); + goto error; + } + } + if (def->cpu && def->cpu->ncells) if (qemuBuildNumaArgStr(def, cmd) < 0) goto error; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args new file mode 100644 index 0000000..f9ef1c1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \ +-S -M pc -m 215 -smp 1 -mem-merge=off -nographic \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi \ +-boot c -usb -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml new file mode 100644 index 0000000..57701a0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml @@ -0,0 +1,29 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219200</memory> + <currentMemory unit='KiB'>219200</currentMemory> + <memoryBacking> + <nosharepages/> + </memoryBacking> + <vcpu placement='static'>1</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> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='ide' index='0'/> + <controller type='usb' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 4bf13f0..48aa07e 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -433,6 +433,7 @@ mymain(void) DO_TEST("hyperv", NONE); DO_TEST("hugepages", QEMU_CAPS_MEM_PATH); + DO_TEST("nosharepages", QEMU_CAPS_MEM_MERGE); DO_TEST("disk-cdrom", NONE); DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE); DO_TEST("disk-cdrom-tray", diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 7434190..c16f866 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -157,6 +157,7 @@ mymain(void) DO_TEST("hyperv"); DO_TEST("hugepages"); + DO_TEST("nosharepages"); DO_TEST("disk-aio"); DO_TEST("disk-cdrom"); DO_TEST("disk-floppy"); -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list