@@ -50,9 +50,11 @@ extern QEMUClockType rtc_clock;
typedef enum {
MLOCK_OFF = 0,
MLOCK_ON,
+ MLOCK_ON_FAULT,
} MlockState;
bool should_mlock(MlockState);
+bool is_mlock_on_fault(MlockState);
extern MlockState mlock_state;
@@ -652,7 +652,7 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
}
if (should_mlock(mlock_state)) {
- if (os_mlock(false) < 0) {
+ if (os_mlock(is_mlock_on_fault(mlock_state)) < 0) {
error_report("mlock: %s", strerror(errno));
/*
* It doesn't feel right to fail at this point, we have a valid
@@ -4632,21 +4632,25 @@ SRST
ERST
DEF("overcommit", HAS_ARG, QEMU_OPTION_overcommit,
- "-overcommit [mem-lock=on|off][cpu-pm=on|off]\n"
+ "-overcommit [mem-lock=on|off|on-fault][cpu-pm=on|off]\n"
" run qemu with overcommit hints\n"
- " mem-lock=on|off controls memory lock support (default: off)\n"
+ " mem-lock=on|off|on-fault controls memory lock support (default: off)\n"
" cpu-pm=on|off controls cpu power management (default: off)\n",
QEMU_ARCH_ALL)
SRST
-``-overcommit mem-lock=on|off``
+``-overcommit mem-lock=on|off|on-fault``
\
``-overcommit cpu-pm=on|off``
Run qemu with hints about host resource overcommit. The default is
to assume that host overcommits all resources.
Locking qemu and guest memory can be enabled via ``mem-lock=on``
- (disabled by default). This works when host memory is not
- overcommitted and reduces the worst-case latency for guest.
+ or ``mem-lock=on-fault`` (disabled by default). This works when
+ host memory is not overcommitted and reduces the worst-case latency for
+ guest. The on-fault option is better for reducing the memory footprint
+ since it makes allocations lazy, but the pages still get locked in place
+ once faulted by the guest or QEMU. Note that the two options are mutually
+ exclusive.
Guest ability to manage power state of host cpus (increasing latency
for other processes on the same host cpu, but decreasing latency for
@@ -33,7 +33,12 @@
bool should_mlock(MlockState state)
{
- return state == MLOCK_ON;
+ return state == MLOCK_ON || state == MLOCK_ON_FAULT;
+}
+
+bool is_mlock_on_fault(MlockState state)
+{
+ return state == MLOCK_ON_FAULT;
}
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
@@ -351,7 +351,7 @@ static QemuOptsList qemu_overcommit_opts = {
.desc = {
{
.name = "mem-lock",
- .type = QEMU_OPT_BOOL,
+ .type = QEMU_OPT_STRING,
},
{
.name = "cpu-pm",
@@ -797,7 +797,7 @@ static QemuOptsList qemu_run_with_opts = {
static void realtime_init(void)
{
if (should_mlock(mlock_state)) {
- if (os_mlock(false) < 0) {
+ if (os_mlock(is_mlock_on_fault(mlock_state)) < 0) {
error_report("locking memory failed");
exit(1);
}
@@ -1878,7 +1878,7 @@ static void object_option_parse(const char *str)
static void overcommit_parse(const char *str)
{
QemuOpts *opts;
- bool enable_mlock;
+ const char *mem_lock_opt;
opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"),
str, false);
@@ -1886,11 +1886,31 @@ static void overcommit_parse(const char *str)
exit(1);
}
- enable_mlock = qemu_opt_get_bool(opts, "mem-lock",
- should_mlock(mlock_state));
- mlock_state = enable_mlock ? MLOCK_ON : MLOCK_OFF;
-
enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", enable_cpu_pm);
+
+ mem_lock_opt = qemu_opt_get(opts, "mem-lock");
+ if (!mem_lock_opt) {
+ return;
+ }
+
+ if (strcmp(mem_lock_opt, "on") == 0) {
+ mlock_state = MLOCK_ON;
+ return;
+ }
+
+ if (strcmp(mem_lock_opt, "off") == 0) {
+ mlock_state = MLOCK_OFF;
+ return;
+ }
+
+ if (strcmp(mem_lock_opt, "on-fault") == 0) {
+ mlock_state = MLOCK_ON_FAULT;
+ return;
+ }
+
+ error_report("parameter 'mem-lock' expects one of "
+ "'on', 'off', 'on-fault'");
+ exit(1);
}
/*