[PATCH v2 7/9] qemu_conf: Introduce a knob to set SCHED_CORE

Michal Privoznik mprivozn at redhat.com
Mon Jun 27 10:44:39 UTC 2022


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



More information about the libvir-list mailing list