---
docs/formatdomain.html.in | 26 +++++++++++++---------
docs/schemas/domaincommon.rng | 5 +++++
src/conf/domain_conf.c | 20 +++++++++--------
src/conf/domain_conf.h | 1 +
src/qemu/qemu_capabilities.c | 2 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 11 +++++++++
tests/qemuxml2argvdata/qemuxml2argv-mlock-off.args | 4 ++++
tests/qemuxml2argvdata/qemuxml2argv-mlock-off.xml | 15 +++++++++++++
tests/qemuxml2argvdata/qemuxml2argv-mlock-on.args | 4 ++++
tests/qemuxml2argvdata/qemuxml2argv-mlock-on.xml | 18 +++++++++++++++
.../qemuxml2argv-mlock-unsupported.args | 4 ++++
.../qemuxml2argv-mlock-unsupported.xml | 15 +++++++++++++
tests/qemuxml2argvtest.c | 5 +++++
14 files changed, 112 insertions(+), 19 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-mlock-off.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-mlock-off.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-mlock-on.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-mlock-on.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 5e89a92..da35d48 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -595,22 +595,28 @@
<memoryBacking>
<hugepages/>
<nosharepages/>
+ <locked/>
</memoryBacking>
...
</domain>
</pre>
+ <p>The optional <code>memoryBacking</code> element may contain
several
+ elements that influence how virtual memory pages are backed by host
+ pages.</p>
+
<dl>
- <dt><code>memoryBacking</code></dt>
- <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>
- (<span class="since">since 1.0.6</span>) tells the
hypervisor
- that share pages (memory merge, KSM) should be disabled on guest
- startup.
- </dd>
+ <dt><code>hugepages</code></dt>
+ <dd>This tells the hypervisor that the guest should have its memory
+ allocated using hugepages instead of the normal native page size.</dd>
+ <dt><code>nosharepages</code></dt>
+ <dd>Instructs hypervisor to disable shared pages (memory merge, KSM) for
+ this domain. <span class="since">Since
1.0.6</span></dd>
+ <dt><code>locked</code></dt>
+ <dd>When set and supported by the hypervisor, memory pages belonging
+ to the domain will be locked in host's memory and the host will not
+ be allowed to swap them out.
+ <span class="since">Since 1.0.6</span></dd>
</dl>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 361794e..f3d3560 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -501,6 +501,11 @@
<empty/>
</element>
</optional>
+ <optional>
+ <element name="locked">
+ <empty/>
+ </element>
+ </optional>
</interleave>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f0ca9d5..6d8e580 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -10389,6 +10389,9 @@ virDomainDefParseXML(xmlDocPtr xml,
if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt)))
def->mem.nosharepages = true;
+ if (virXPathBoolean("boolean(./memoryBacking/locked)", ctxt))
+ def->mem.locked = true;
+
/* Extract blkio cgroup tunables */
if (virXPathUInt("string(./blkiotune/weight)", ctxt,
&def->blkio.weight) < 0)
@@ -15736,17 +15739,16 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->mem.swap_hard_limit)
virBufferAddLit(buf, " </memtune>\n");
- if (def->mem.hugepage_backed || def->mem.nosharepages)
+ if (def->mem.hugepage_backed || def->mem.nosharepages || def->mem.locked) {
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)
+ if (def->mem.hugepage_backed)
+ virBufferAddLit(buf, " <hugepages/>\n");
+ if (def->mem.nosharepages)
+ virBufferAddLit(buf, " <nosharepages/>\n");
+ if (def->mem.locked)
+ virBufferAddLit(buf, " <locked/>\n");
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 c176a4c..16eb8b6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1861,6 +1861,7 @@ struct _virDomainDef {
unsigned long long cur_balloon; /* in kibibytes */
bool hugepage_backed;
bool nosharepages;
+ bool locked;
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 488cbfe..82129a2 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -230,6 +230,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"mem-merge",
"vnc-websocket",
"drive-discard",
+ "mlock",
);
struct _virQEMUCaps {
@@ -2246,6 +2247,7 @@ struct virQEMUCapsCommandLineProps {
static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
{ "machine", "mem-merge", QEMU_CAPS_MEM_MERGE },
{ "drive", "discard", QEMU_CAPS_DRIVE_DISCARD },
+ { "realtime", "mlock", QEMU_CAPS_MLOCK },
};
static int
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 173ca77..117bf8a 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -187,6 +187,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_MEM_MERGE = 146, /* -machine mem-merge */
QEMU_CAPS_VNC_WEBSOCKET = 147, /* -vnc x:y,websocket */
QEMU_CAPS_DRIVE_DISCARD = 148, /* -drive discard=off(ignore)|on(unmap) */
+ QEMU_CAPS_MLOCK = 149, /* -realtime mlock=on|off */
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 5b95c07..c268a3a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6541,6 +6541,17 @@ qemuBuildCommandLine(virConnectPtr conn,
cfg->hugepagePath, NULL);
}
+ if (def->mem.locked && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MLOCK)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("memory locking not supported by QEMU binary"));
+ goto error;
+ }
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MLOCK)) {
+ virCommandAddArg(cmd, "-realtime");
+ virCommandAddArgFormat(cmd, "mlock=%s",
+ def->mem.locked ? "on" : "off");
+ }
+
virCommandAddArg(cmd, "-smp");
if (!(smp = qemuBuildSmpArgStr(def, qemuCaps)))
goto error;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-mlock-off.args
b/tests/qemuxml2argvdata/qemuxml2argv-mlock-off.args
new file mode 100644
index 0000000..2a5d94c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-mlock-off.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
+/usr/bin/qemu -S -M pc -m 214 -realtime mlock=off \
+-smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi -boot c -usb -net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-mlock-off.xml
b/tests/qemuxml2argvdata/qemuxml2argv-mlock-off.xml
new file mode 100644
index 0000000..4125ca5
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-mlock-off.xml
@@ -0,0 +1,15 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-mlock-on.args
b/tests/qemuxml2argvdata/qemuxml2argv-mlock-on.args
new file mode 100644
index 0000000..bb6de13
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-mlock-on.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
+/usr/bin/qemu -S -M pc -m 214 -realtime mlock=on \
+-smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi -boot c -usb -net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-mlock-on.xml
b/tests/qemuxml2argvdata/qemuxml2argv-mlock-on.xml
new file mode 100644
index 0000000..20a5eaa
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-mlock-on.xml
@@ -0,0 +1,18 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <memoryBacking>
+ <locked/>
+ </memoryBacking>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.args
b/tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.args
new file mode 100644
index 0000000..54dd3b9
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
+/usr/bin/qemu -S -M pc -m 214 \
+-smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi -boot c -usb -net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.xml
b/tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.xml
new file mode 100644
index 0000000..4125ca5
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-mlock-unsupported.xml
@@ -0,0 +1,15 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index c751440..d853308 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1007,6 +1007,11 @@ mymain(void)
QEMU_CAPS_DEVICE_SCSI_GENERIC,
QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX);
+ DO_TEST("mlock-on", QEMU_CAPS_MLOCK);
+ DO_TEST_FAILURE("mlock-on", NONE);
+ DO_TEST("mlock-off", QEMU_CAPS_MLOCK);
+ DO_TEST("mlock-unsupported", NONE);
+
virObjectUnref(driver.config);
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
--
1.8.2.1