qemu: New XML to disable memory merge at guest startup

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.
This commit is contained in:
Osier Yang 2013-05-14 13:25:50 +08:00
parent d12bbd6a7d
commit 77b54b9661
10 changed files with 98 additions and 15 deletions

View File

@ -561,6 +561,7 @@
... ...
&lt;memoryBacking&gt; &lt;memoryBacking&gt;
&lt;hugepages/&gt; &lt;hugepages/&gt;
&lt;nosharepages/&gt;
&lt;/memoryBacking&gt; &lt;/memoryBacking&gt;
... ...
&lt;/domain&gt; &lt;/domain&gt;
@ -568,10 +569,15 @@
<dl> <dl>
<dt><code>memoryBacking</code></dt> <dt><code>memoryBacking</code></dt>
<dd>The optional <code>memoryBacking</code> element, may have an <dd>The optional <code>memoryBacking</code> element has two
<code>hugepages</code> element set within it. This tells the optional elements. The element <code>hugepages</code> tells
hypervisor that the guest should have its memory allocated using the hypervisor that the guest should have its memory allocated
hugepages instead of the normal native page size.</dd> using hugepages instead of the normal native page size. And the
optional element <code>nosharepages</code>
(<span class="since">since 1.0.6</span>) tells the hypervisor
that share pages (memory merge, KSM) should be disabled on guest
startup.
</dd>
</dl> </dl>

View File

@ -490,11 +490,18 @@
</optional> </optional>
<optional> <optional>
<element name="memoryBacking"> <element name="memoryBacking">
<interleave>
<optional> <optional>
<element name="hugepages"> <element name="hugepages">
<empty/> <empty/>
</element> </element>
</optional> </optional>
<optional>
<element name="nosharepages">
<empty/>
</element>
</optional>
</interleave>
</element> </element>
</optional> </optional>

View File

@ -10306,6 +10306,9 @@ virDomainDefParseXML(xmlDocPtr xml,
if ((node = virXPathNode("./memoryBacking/hugepages", ctxt))) if ((node = virXPathNode("./memoryBacking/hugepages", ctxt)))
def->mem.hugepage_backed = true; def->mem.hugepage_backed = true;
if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt)))
def->mem.nosharepages = true;
/* Extract blkio cgroup tunables */ /* Extract blkio cgroup tunables */
if (virXPathUInt("string(./blkiotune/weight)", ctxt, if (virXPathUInt("string(./blkiotune/weight)", ctxt,
&def->blkio.weight) < 0) &def->blkio.weight) < 0)
@ -15662,12 +15665,17 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->mem.swap_hard_limit) def->mem.swap_hard_limit)
virBufferAddLit(buf, " </memtune>\n"); virBufferAddLit(buf, " </memtune>\n");
if (def->mem.hugepage_backed) { if (def->mem.hugepage_backed || def->mem.nosharepages)
virBufferStrcat(buf, virBufferAddLit(buf, " <memoryBacking>\n");
" <memoryBacking>\n",
" <hugepages/>\n", if (def->mem.hugepage_backed)
" </memoryBacking>\n", NULL); 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"); virBufferAddLit(buf, " <vcpu");
virBufferAsprintf(buf, " placement='%s'", virBufferAsprintf(buf, " placement='%s'",

View File

@ -1850,6 +1850,7 @@ struct _virDomainDef {
unsigned long long max_balloon; /* in kibibytes */ unsigned long long max_balloon; /* in kibibytes */
unsigned long long cur_balloon; /* in kibibytes */ unsigned long long cur_balloon; /* in kibibytes */
bool hugepage_backed; bool hugepage_backed;
bool nosharepages;
int dump_core; /* enum virDomainMemDump */ int dump_core; /* enum virDomainMemDump */
unsigned long long hard_limit; /* in kibibytes */ unsigned long long hard_limit; /* in kibibytes */
unsigned long long soft_limit; /* in kibibytes */ unsigned long long soft_limit; /* in kibibytes */

View File

@ -5845,6 +5845,14 @@ qemuBuildMachineArgStr(virCommandPtr cmd,
"with this QEMU binary")); "with this QEMU binary"));
return -1; 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; obsoleteAccel = true;
} else { } else {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
@ -5878,6 +5886,18 @@ qemuBuildMachineArgStr(virCommandPtr cmd,
virDomainMemDumpTypeToString(def->mem.dump_core)); 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); virCommandAddArgBuffer(cmd, &buf);
} }
@ -10183,6 +10203,8 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
def->mem.dump_core = VIR_DOMAIN_MEM_DUMP_DEFAULT; def->mem.dump_core = VIR_DOMAIN_MEM_DUMP_DEFAULT;
if (params) if (params)
VIR_FREE(tmp); VIR_FREE(tmp);
} else if (STRPREFIX(tmp, "mem-merge=off")) {
def->mem.nosharepages = true;
} }
} }
} }

View File

@ -246,6 +246,8 @@ mymain(void)
DO_TEST("pseries-nvram"); DO_TEST("pseries-nvram");
DO_TEST("nosharepages");
DO_TEST_FULL("restore-v1", 0, "stdio"); DO_TEST_FULL("restore-v1", 0, "stdio");
DO_TEST_FULL("restore-v2", 0, "stdio"); DO_TEST_FULL("restore-v2", 0, "stdio");
DO_TEST_FULL("restore-v2", 0, "exec:cat"); DO_TEST_FULL("restore-v2", 0, "exec:cat");

View File

@ -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

View File

@ -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>

View File

@ -439,6 +439,7 @@ mymain(void)
DO_TEST("hyperv", NONE); DO_TEST("hyperv", NONE);
DO_TEST("hugepages", QEMU_CAPS_MEM_PATH); 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", NONE);
DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE); DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-tray", DO_TEST("disk-cdrom-tray",

View File

@ -158,6 +158,7 @@ mymain(void)
DO_TEST("hyperv"); DO_TEST("hyperv");
DO_TEST("hugepages"); DO_TEST("hugepages");
DO_TEST("nosharepages");
DO_TEST("disk-aio"); DO_TEST("disk-aio");
DO_TEST("disk-cdrom"); DO_TEST("disk-cdrom");
DO_TEST("disk-floppy"); DO_TEST("disk-floppy");