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_command.c | 22 +++++++++++++++ tests/qemuargv2xmltest.c | 2 ++ .../qemuxml2argv-nosharepages.args | 4 +++ .../qemuxml2argvdata/qemuxml2argv-nosharepages.xml | 31 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmltest.c | 1 + 10 files changed, 90 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 9ade507..3a6c18f 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -561,6 +561,7 @@ ... <memoryBacking> <hugepages/> + <nosharepages/> </memoryBacking> ... </domain> @@ -568,10 +569,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 8004428..2e0e28e 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 862b997..2ab1bf8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10306,6 +10306,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) @@ -15662,12 +15665,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 a9d3410..1151111 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1850,6 +1850,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_command.c b/src/qemu/qemu_command.c index eddc263..a9d71de 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5838,6 +5838,14 @@ qemuBuildMachineArgStr(virCommandPtr cmd, "with this QEMU binary")); return -1; } + + if (def->mem.nosharepages) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disable shared memory is not available " + "with this QEMU binary")); + return -1; + } + obsoleteAccel = true; } else { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -5871,6 +5879,18 @@ qemuBuildMachineArgStr(virCommandPtr cmd, virDomainMemDumpTypeToString(def->mem.dump_core)); } + if (def->mem.nosharepages) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_MERGE)) { + virBufferAddLit(&buf, ",mem-merge=off"); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disable shared memory is not available " + "with this QEMU binary")); + virBufferFreeAndReset(&buf); + return -1; + } + } + virCommandAddArgBuffer(cmd, &buf); } @@ -10176,6 +10196,8 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps, def->mem.dump_core = VIR_DOMAIN_MEM_DUMP_DEFAULT; if (params) VIR_FREE(tmp); + } else if (STRPREFIX(tmp, "mem-merge=off")) { + def->mem.nosharepages = true; } } } diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index 005aa0c..528b8bf 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -246,6 +246,8 @@ mymain(void) DO_TEST("pseries-nvram"); + DO_TEST("nosharepages"); + DO_TEST_FULL("restore-v1", 0, "stdio"); DO_TEST_FULL("restore-v2", 0, "stdio"); DO_TEST_FULL("restore-v2", 0, "exec:cat"); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args new file mode 100644 index 0000000..a32dfe5 --- /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 -machine pc,accel=tcg,mem-merge=off -m 215 -smp 1 -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..5e54cd0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml @@ -0,0 +1,31 @@ +<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'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 98ceb83..a45fa9a 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -436,6 +436,7 @@ mymain(void) DO_TEST("hyperv", NONE); DO_TEST("hugepages", QEMU_CAPS_MEM_PATH); + DO_TEST("nosharepages", QEMU_CAPS_MACHINE_OPT, 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 492ac60..ddf3230 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -158,6 +158,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