Ideally, we would just pick the best default and users wouldn't
have to intervene at all. But in some cases it may be handy to
not bother with SCHED_CORE at all or place helper processes into
the same group as QEMU. Introduce a knob in qemu.conf to allow
users control this behaviour.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf.in | 14 ++++++++++
src/qemu/qemu_conf.c | 42 ++++++++++++++++++++++++++++++
src/qemu/qemu_conf.h | 11 ++++++++
src/qemu/test_libvirtd_qemu.aug.in | 1 +
5 files changed, 69 insertions(+)
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index 0f18775121..ed097ea3d9 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -110,6 +110,7 @@ module Libvirtd_qemu =
| bool_entry "dump_guest_core"
| str_entry "stdio_handler"
| int_entry "max_threads_per_process"
+ | str_entry "sched_core"
let device_entry = bool_entry "mac_filter"
| bool_entry "relaxed_acs_check"
diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in
index 04b7740136..01c7ab5868 100644
--- a/src/qemu/qemu.conf.in
+++ b/src/qemu/qemu.conf.in
@@ -952,3 +952,17 @@
# DO NOT use in production.
#
#deprecation_behavior = "none"
+
+# If this is set then QEMU and its threads will run in a separate scheduling
+# group meaning no other process will share Hyper Threads of a single core with
+# QEMU. Each QEMU has its own group.
+#
+# Possible options are:
+# "none" - nor QEMU nor any of its helper processes are placed into separate
+# scheduling group
+# "emulator" - (default) only QEMU and its threads (emulator + vCPUs) are
+# placed into separate scheduling group, helper proccesses remain
+# outside of the group.
+# "full" - both QEMU and its helper processes are placed into separate
+# scheduling group.
+#sched_core = "emulator"
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 3b75cdeb95..d2c0dbf981 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -66,6 +66,14 @@ VIR_LOG_INIT("qemu.qemu_conf");
#define QEMU_MIGRATION_PORT_MIN 49152
#define QEMU_MIGRATION_PORT_MAX 49215
+VIR_ENUM_DECL(virQEMUSchedCore);
+VIR_ENUM_IMPL(virQEMUSchedCore,
+ QEMU_SCHED_CORE_LAST,
+ "none",
+ "emulator",
+ "full");
+
+
static virClass *virQEMUDriverConfigClass;
static void virQEMUDriverConfigDispose(void *obj);
@@ -281,6 +289,9 @@ virQEMUDriverConfig *virQEMUDriverConfigNew(bool privileged,
cfg->deprecationBehavior = g_strdup("none");
+ if (virProcessSchedCoreAvailable() > 0)
+ cfg->schedCore = QEMU_SCHED_CORE_EMULATOR;
+
return g_steal_pointer(&cfg);
}
@@ -629,6 +640,7 @@ virQEMUDriverConfigLoadProcessEntry(virQEMUDriverConfig *cfg,
g_auto(GStrv) hugetlbfs = NULL;
g_autofree char *stdioHandler = NULL;
g_autofree char *corestr = NULL;
+ g_autofree char *schedCore = NULL;
size_t i;
if (virConfGetValueStringList(conf, "hugetlbfs_mount", true,
@@ -706,6 +718,36 @@ virQEMUDriverConfigLoadProcessEntry(virQEMUDriverConfig *cfg,
}
}
+ if (virConfGetValueString(conf, "sched_core", &schedCore) < 0)
+ return -1;
+ if (schedCore) {
+ int val = virQEMUSchedCoreTypeFromString(schedCore);
+
+ if (val < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unknown sched_core value %s"),
+ schedCore);
+ return -1;
+ }
+
+ if (val == QEMU_SCHED_CORE_EMULATOR ||
+ val == QEMU_SCHED_CORE_FULL) {
+ int rv = virProcessSchedCoreAvailable();
+
+ if (rv < 0) {
+ virReportSystemError(errno, "%s",
+ _("Unable to detect SCHED_CORE"));
+ return -1;
+ } else if (rv == 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("SCHED_CORE not supported by kernel"));
+ return -1;
+ }
+ }
+
+ cfg->schedCore = val;
+ }
+
return 0;
}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index c40c452f58..afc1af6073 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -44,6 +44,15 @@
#define QEMU_DRIVER_NAME "QEMU"
+typedef enum {
+ QEMU_SCHED_CORE_NONE = 0,
+ QEMU_SCHED_CORE_EMULATOR,
+ QEMU_SCHED_CORE_FULL,
+
+ QEMU_SCHED_CORE_LAST
+} virQEMUSchedCore;
+
+
typedef struct _virQEMUDriver virQEMUDriver;
typedef struct _virQEMUDriverConfig virQEMUDriverConfig;
@@ -216,6 +225,8 @@ struct _virQEMUDriverConfig {
char **capabilityfilters;
char *deprecationBehavior;
+
+ virQEMUSchedCore schedCore;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDriverConfig, virObjectUnref);
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
index 757d21c33f..17caffdbd3 100644
--- a/src/qemu/test_libvirtd_qemu.aug.in
+++ b/src/qemu/test_libvirtd_qemu.aug.in
@@ -116,3 +116,4 @@ module Test_libvirtd_qemu =
{ "1" = "capname" }
}
{ "deprecation_behavior" = "none" }
+{ "sched_core" = "emulator" }
--
2.35.1