182 lines
6.7 KiB
Diff
182 lines
6.7 KiB
Diff
From 1cfbcbeebc6d9ca1f1f7656fff572bf6ac50de76 Mon Sep 17 00:00:00 2001
|
|
From: "plai@redhat.com" <plai@redhat.com>
|
|
Date: Tue, 26 Nov 2019 19:36:52 +0000
|
|
Subject: [PATCH 08/11] kvm: support -overcommit cpu-pm=on|off
|
|
|
|
RH-Author: plai@redhat.com
|
|
Message-id: <1574797015-32564-5-git-send-email-plai@redhat.com>
|
|
Patchwork-id: 92697
|
|
O-Subject: [RHEL8.2 qemu-kvm PATCH 4/7] kvm: support -overcommit cpu-pm=on|off
|
|
Bugzilla: 1634827
|
|
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
|
|
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
|
|
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
|
|
|
|
From: "Michael S. Tsirkin" <mst@redhat.com>
|
|
|
|
With this flag, kvm allows guest to control host CPU power state. This
|
|
increases latency for other processes using same host CPU in an
|
|
unpredictable way, but if decreases idle entry/exit times for the
|
|
running VCPU, so to use it QEMU needs a hint about whether host CPU is
|
|
overcommitted, hence the flag name.
|
|
|
|
Follow-up patches will expose this capability to guest
|
|
(using mwait leaf).
|
|
|
|
Based on a patch by Wanpeng Li <kernellwp@gmail.com> .
|
|
|
|
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
|
Message-Id: <20180622192148.178309-2-mst@redhat.com>
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
(cherry picked from commit 6f131f13e68d648a8e4f083c667ab1acd88ce4cd)
|
|
Signed-off-by: Paul Lai <plai@redhat.com>
|
|
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
---
|
|
include/sysemu/sysemu.h | 1 +
|
|
qemu-options.hx | 24 ++++++++++++++++++++++++
|
|
target/i386/kvm.c | 23 +++++++++++++++++++++++
|
|
vl.c | 32 +++++++++++++++++++++++++++++++-
|
|
4 files changed, 79 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
|
|
index f20e4f5..f38fad0 100644
|
|
--- a/include/sysemu/sysemu.h
|
|
+++ b/include/sysemu/sysemu.h
|
|
@@ -131,6 +131,7 @@ extern bool boot_strict;
|
|
extern uint8_t *boot_splash_filedata;
|
|
extern size_t boot_splash_filedata_size;
|
|
extern bool enable_mlock;
|
|
+extern bool enable_cpu_pm;
|
|
extern uint8_t qemu_extra_params_fw[2];
|
|
extern QEMUClockType rtc_clock;
|
|
extern const char *mem_path;
|
|
diff --git a/qemu-options.hx b/qemu-options.hx
|
|
index 1243057..99933a0 100644
|
|
--- a/qemu-options.hx
|
|
+++ b/qemu-options.hx
|
|
@@ -3331,6 +3331,30 @@ mlocking qemu-kvm and guest memory can be enabled via @option{mlock=on}
|
|
(enabled by default).
|
|
ETEXI
|
|
|
|
+DEF("overcommit", HAS_ARG, QEMU_OPTION_overcommit,
|
|
+ "--overcommit [mem-lock=on|off][cpu-pm=on|off]\n"
|
|
+ " run qemu with overcommit hints\n"
|
|
+ " mem-lock=on|off controls memory lock support (default: off)\n"
|
|
+ " cpu-pm=on|off controls cpu power management (default: off)\n",
|
|
+ QEMU_ARCH_ALL)
|
|
+STEXI
|
|
+@item -overcommit mem-lock=on|off
|
|
+@item -overcommit cpu-pm=on|off
|
|
+@findex -overcommit
|
|
+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 @option{mem-lock=on} (disabled
|
|
+by default). This works when host memory is not overcommitted and reduces the
|
|
+worst-case latency for guest. This is equivalent to @option{realtime}.
|
|
+
|
|
+Guest ability to manage power state of host cpus (increasing latency for other
|
|
+processes on the same host cpu, but decreasing latency for guest) can be
|
|
+enabled via @option{cpu-pm=on} (disabled by default). This works best when
|
|
+host CPU is not overcommitted. When used, host estimates of CPU cycle and power
|
|
+utilization will be incorrect, not taking into account guest idle time.
|
|
+ETEXI
|
|
+
|
|
DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
|
|
"-gdb dev wait for gdb connection on 'dev'\n", QEMU_ARCH_ALL)
|
|
STEXI
|
|
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
|
|
index 107c53b..879c3e0 100644
|
|
--- a/target/i386/kvm.c
|
|
+++ b/target/i386/kvm.c
|
|
@@ -1606,6 +1606,29 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
|
smram_machine_done.notify = register_smram_listener;
|
|
qemu_add_machine_init_done_notifier(&smram_machine_done);
|
|
}
|
|
+
|
|
+ if (enable_cpu_pm) {
|
|
+ int disable_exits = kvm_check_extension(s, KVM_CAP_X86_DISABLE_EXITS);
|
|
+ int ret;
|
|
+
|
|
+/* Work around for kernel header with a typo. TODO: fix header and drop. */
|
|
+#if defined(KVM_X86_DISABLE_EXITS_HTL) && !defined(KVM_X86_DISABLE_EXITS_HLT)
|
|
+#define KVM_X86_DISABLE_EXITS_HLT KVM_X86_DISABLE_EXITS_HTL
|
|
+#endif
|
|
+ if (disable_exits) {
|
|
+ disable_exits &= (KVM_X86_DISABLE_EXITS_MWAIT |
|
|
+ KVM_X86_DISABLE_EXITS_HLT |
|
|
+ KVM_X86_DISABLE_EXITS_PAUSE);
|
|
+ }
|
|
+
|
|
+ ret = kvm_vm_enable_cap(s, KVM_CAP_X86_DISABLE_EXITS, 0,
|
|
+ disable_exits);
|
|
+ if (ret < 0) {
|
|
+ error_report("kvm: guest stopping CPU not supported: %s",
|
|
+ strerror(-ret));
|
|
+ }
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/vl.c b/vl.c
|
|
index 932c1cf..aa08ab5 100644
|
|
--- a/vl.c
|
|
+++ b/vl.c
|
|
@@ -150,6 +150,7 @@ ram_addr_t ram_size;
|
|
const char *mem_path = NULL;
|
|
int mem_prealloc = 0; /* force preallocation of physical target memory */
|
|
bool enable_mlock = false;
|
|
+bool enable_cpu_pm = false;
|
|
int nb_nics;
|
|
NICInfo nd_table[MAX_NICS];
|
|
int autostart;
|
|
@@ -428,6 +429,22 @@ static QemuOptsList qemu_realtime_opts = {
|
|
},
|
|
};
|
|
|
|
+static QemuOptsList qemu_overcommit_opts = {
|
|
+ .name = "overcommit",
|
|
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
|
|
+ .desc = {
|
|
+ {
|
|
+ .name = "mem-lock",
|
|
+ .type = QEMU_OPT_BOOL,
|
|
+ },
|
|
+ {
|
|
+ .name = "cpu-pm",
|
|
+ .type = QEMU_OPT_BOOL,
|
|
+ },
|
|
+ { /* end of list */ }
|
|
+ },
|
|
+};
|
|
+
|
|
static QemuOptsList qemu_msg_opts = {
|
|
.name = "msg",
|
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head),
|
|
@@ -4089,7 +4106,20 @@ int main(int argc, char **argv, char **envp)
|
|
if (!opts) {
|
|
exit(1);
|
|
}
|
|
- enable_mlock = qemu_opt_get_bool(opts, "mlock", true);
|
|
+ /* Don't override the -overcommit option if set */
|
|
+ enable_mlock = enable_mlock ||
|
|
+ qemu_opt_get_bool(opts, "mlock", true);
|
|
+ break;
|
|
+ case QEMU_OPTION_overcommit:
|
|
+ opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"),
|
|
+ optarg, false);
|
|
+ if (!opts) {
|
|
+ exit(1);
|
|
+ }
|
|
+ /* Don't override the -realtime option if set */
|
|
+ enable_mlock = enable_mlock ||
|
|
+ qemu_opt_get_bool(opts, "mem-lock", false);
|
|
+ enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false);
|
|
break;
|
|
case QEMU_OPTION_msg:
|
|
opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg,
|
|
--
|
|
1.8.3.1
|
|
|