]> xenbits.xensource.com Git - people/larsk/xen.git/commitdiff
xen/sched: add scheduling granularity enum
authorJuergen Gross <jgross@suse.com>
Wed, 2 Oct 2019 07:27:44 +0000 (09:27 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 4 Oct 2019 11:03:43 +0000 (13:03 +0200)
Add a scheduling granularity enum ("cpu", "core", "socket") for
specification of the scheduling granularity. Initially it is set to
"cpu", this can be modified by the new boot parameter (x86 only)
"sched-gran".

According to the selected granularity sched_granularity is set after
all cpus are online.

A test is added for all sched resources holding the same number of
cpus. Fall back to core- or cpu-scheduling in that case.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
xen/arch/x86/Kconfig
xen/common/Kconfig
xen/common/cpupool.c

index 288dc6c042c9d1410c70cb49a943522c321a1991..3f88adae978f316be140f4bb943ed04ed59a0230 100644 (file)
@@ -22,6 +22,7 @@ config X86
        select HAS_PASSTHROUGH
        select HAS_PCI
        select HAS_PDX
+       select HAS_SCHED_GRANULARITY
        select HAS_UBSAN
        select HAS_VPCI if !PV_SHIM_EXCLUSIVE && HVM
        select NEEDS_LIBELF
index 16829f62741c738d750f4ec27f3ae1cb88f68206..e9247871a8ec38ea7d220e079a3a80860e07a005 100644 (file)
@@ -63,6 +63,9 @@ config HAS_GDBSX
 config HAS_IOPORTS
        bool
 
+config HAS_SCHED_GRANULARITY
+       bool
+
 config NEEDS_LIBELF
        bool
 
index f7a13c7a4cbcbb0d085ca984f636b95cf1e6a164..4d3adbdd8d4ddc0cced7d70ed813b4e5d61bd7bd 100644 (file)
@@ -17,6 +17,7 @@
 #include <xen/percpu.h>
 #include <xen/sched.h>
 #include <xen/sched-if.h>
+#include <xen/warning.h>
 #include <xen/keyhandler.h>
 #include <xen/cpu.h>
 
@@ -37,6 +38,83 @@ static DEFINE_SPINLOCK(cpupool_lock);
 static enum sched_gran __read_mostly opt_sched_granularity = SCHED_GRAN_cpu;
 static unsigned int __read_mostly sched_granularity = 1;
 
+#ifdef CONFIG_HAS_SCHED_GRANULARITY
+static int __init sched_select_granularity(const char *str)
+{
+    if ( strcmp("cpu", str) == 0 )
+        opt_sched_granularity = SCHED_GRAN_cpu;
+    else if ( strcmp("core", str) == 0 )
+        opt_sched_granularity = SCHED_GRAN_core;
+    else if ( strcmp("socket", str) == 0 )
+        opt_sched_granularity = SCHED_GRAN_socket;
+    else
+        return -EINVAL;
+
+    return 0;
+}
+custom_param("sched-gran", sched_select_granularity);
+#endif
+
+static unsigned int __init cpupool_check_granularity(void)
+{
+    unsigned int cpu;
+    unsigned int siblings, gran = 0;
+
+    if ( opt_sched_granularity == SCHED_GRAN_cpu )
+        return 1;
+
+    for_each_online_cpu ( cpu )
+    {
+        siblings = cpumask_weight(sched_get_opt_cpumask(opt_sched_granularity,
+                                                        cpu));
+        if ( gran == 0 )
+            gran = siblings;
+        else if ( gran != siblings )
+            return 0;
+    }
+
+    sched_disable_smt_switching = true;
+
+    return gran;
+}
+
+/* Setup data for selected scheduler granularity. */
+static void __init cpupool_gran_init(void)
+{
+    unsigned int gran = 0;
+    const char *fallback = NULL;
+
+    while ( gran == 0 )
+    {
+        gran = cpupool_check_granularity();
+
+        if ( gran == 0 )
+        {
+            switch ( opt_sched_granularity )
+            {
+            case SCHED_GRAN_core:
+                opt_sched_granularity = SCHED_GRAN_cpu;
+                fallback = "Asymmetric cpu configuration.\n"
+                           "Falling back to sched-gran=cpu.\n";
+                break;
+            case SCHED_GRAN_socket:
+                opt_sched_granularity = SCHED_GRAN_core;
+                fallback = "Asymmetric cpu configuration.\n"
+                           "Falling back to sched-gran=core.\n";
+                break;
+            default:
+                ASSERT_UNREACHABLE();
+                break;
+            }
+        }
+    }
+
+    if ( fallback )
+        warning_add(fallback);
+
+    sched_granularity = gran;
+}
+
 unsigned int cpupool_get_granularity(const struct cpupool *c)
 {
     return c ? sched_granularity : 1;
@@ -871,6 +949,8 @@ static int __init cpupool_init(void)
     unsigned int cpu;
     int err;
 
+    cpupool_gran_init();
+
     cpupool0 = cpupool_create(0, 0, &err);
     BUG_ON(cpupool0 == NULL);
     cpupool_put(cpupool0);