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..623da72d60 100644 --- a/src/qemu/qemu.conf.in +++ b/src/qemu/qemu.conf.in @@ -952,3 +952,19 @@ # 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" - (default) neither QEMU or any of its helper processes are placed +# into separate scheduling group +# "vcpus" - only QEMU vCPU threads are placed into a separate scheduling group, +# emulator threads and helper processes remain outside of the group +# "emulator" - 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 = "none" diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 8de887d1fa..ae5bbcd138 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_IMPL(virQEMUSchedCore, + QEMU_SCHED_CORE_LAST, + "none", + "vcpus", + "emulator", + "full"); + + static virClass *virQEMUDriverConfigClass; static void virQEMUDriverConfigDispose(void *obj); @@ -629,6 +637,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 +715,35 @@ 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_NONE) { + 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 ac911b03c2..8cf2dd2ec5 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -44,6 +44,17 @@ #define QEMU_DRIVER_NAME "QEMU" +typedef enum { + QEMU_SCHED_CORE_NONE = 0, + QEMU_SCHED_CORE_VCPUS, + QEMU_SCHED_CORE_EMULATOR, + QEMU_SCHED_CORE_FULL, + + QEMU_SCHED_CORE_LAST +} virQEMUSchedCore; + +VIR_ENUM_DECL(virQEMUSchedCore); + typedef struct _virQEMUDriver virQEMUDriver; typedef struct _virQEMUDriverConfig virQEMUDriverConfig; @@ -216,6 +227,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..1dbd692921 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" = "none" }