aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Chen <tim.c.chen@linux.intel.com>2016-11-22 15:23:55 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-11-24 14:44:19 -0500
commit5e76b2ab36b40ca33023e78725bdc69eafd63134 (patch)
treeda9908c253b620ffad1bc413878d3e9a1b5fc654
parent7d25127cef44924f1013d119ba385095ca4b4a83 (diff)
x86: Enable Intel Turbo Boost Max Technology 3.0
On platforms supporting Intel Turbo Boost Max Technology 3.0, the maximum turbo frequencies of some cores in a CPU package may be higher than for the other cores in the same package. In that case, better performance (and possibly lower energy consumption as well) can be achieved by making the scheduler prefer to run tasks on the CPUs with higher max turbo frequencies. To that end, set up a core priority metric to abstract the core preferences based on the maximum turbo frequency. In that metric, the cores with higher maximum turbo frequencies are higher-priority than the other cores in the same package and that causes the scheduler to favor them when making load-balancing decisions using the asymmertic packing approach. At the same time, the priority of SMT threads with a higher CPU number is reduced so as to avoid scheduling tasks on all of the threads that belong to a favored core before all of the other cores have been given a task to run. The priority metric will be initialized by the P-state driver with the help of the sched_set_itmt_core_prio() function. The P-state driver will also determine whether or not ITMT is supported by the platform and will call sched_set_itmt_support() to indicate that. Co-developed-by: Peter Zijlstra (Intel) <peterz@infradead.org> Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com> Cc: linux-pm@vger.kernel.org Cc: peterz@infradead.org Cc: jolsa@redhat.com Cc: rjw@rjwysocki.net Cc: linux-acpi@vger.kernel.org Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Cc: bp@suse.de Link: http://lkml.kernel.org/r/cd401ccdff88f88c8349314febdc25d51f7c48f7.1479844244.git.tim.c.chen@linux.intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/Kconfig9
-rw-r--r--arch/x86/include/asm/topology.h28
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/itmt.c109
4 files changed, 147 insertions, 0 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636d1065..25950f0ccc33 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -939,6 +939,15 @@ config SCHED_MC
939 making when dealing with multi-core CPU chips at a cost of slightly 939 making when dealing with multi-core CPU chips at a cost of slightly
940 increased overhead in some places. If unsure say N here. 940 increased overhead in some places. If unsure say N here.
941 941
942config SCHED_ITMT
943 bool "Intel Turbo Boost Max Technology (ITMT) scheduler support"
944 depends on SCHED_MC && CPU_SUP_INTEL && X86_INTEL_PSTATE
945 ---help---
946 ITMT enabled scheduler support improves the CPU scheduler's decision
947 to move tasks to cpu core that can be boosted to a higher frequency
948 than others. It will have better performance at a cost of slightly
949 increased overhead in task migrations. If unsure say N here.
950
942source "kernel/Kconfig.preempt" 951source "kernel/Kconfig.preempt"
943 952
944config UP_LATE_INIT 953config UP_LATE_INIT
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index a5ca88a22ca3..8ace9511347c 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -147,4 +147,32 @@ int x86_pci_root_bus_node(int bus);
147void x86_pci_root_bus_resources(int bus, struct list_head *resources); 147void x86_pci_root_bus_resources(int bus, struct list_head *resources);
148 148
149extern bool x86_topology_update; 149extern bool x86_topology_update;
150
151#ifdef CONFIG_SCHED_ITMT
152#include <asm/percpu.h>
153
154DECLARE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
155
156/* Interface to set priority of a cpu */
157void sched_set_itmt_core_prio(int prio, int core_cpu);
158
159/* Interface to notify scheduler that system supports ITMT */
160void sched_set_itmt_support(void);
161
162/* Interface to notify scheduler that system revokes ITMT support */
163void sched_clear_itmt_support(void);
164
165#else /* CONFIG_SCHED_ITMT */
166
167static inline void sched_set_itmt_core_prio(int prio, int core_cpu)
168{
169}
170static inline void sched_set_itmt_support(void)
171{
172}
173static inline void sched_clear_itmt_support(void)
174{
175}
176#endif /* CONFIG_SCHED_ITMT */
177
150#endif /* _ASM_X86_TOPOLOGY_H */ 178#endif /* _ASM_X86_TOPOLOGY_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 79076d75bdbf..bbd0ebcfcc2a 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -123,6 +123,7 @@ obj-$(CONFIG_EFI) += sysfb_efi.o
123 123
124obj-$(CONFIG_PERF_EVENTS) += perf_regs.o 124obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
125obj-$(CONFIG_TRACING) += tracepoint.o 125obj-$(CONFIG_TRACING) += tracepoint.o
126obj-$(CONFIG_SCHED_ITMT) += itmt.o
126 127
127ifdef CONFIG_FRAME_POINTER 128ifdef CONFIG_FRAME_POINTER
128obj-y += unwind_frame.o 129obj-y += unwind_frame.o
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
new file mode 100644
index 000000000000..63c9b3e3509d
--- /dev/null
+++ b/arch/x86/kernel/itmt.c
@@ -0,0 +1,109 @@
1/*
2 * itmt.c: Support Intel Turbo Boost Max Technology 3.0
3 *
4 * (C) Copyright 2016 Intel Corporation
5 * Author: Tim Chen <tim.c.chen@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 *
12 * On platforms supporting Intel Turbo Boost Max Technology 3.0, (ITMT),
13 * the maximum turbo frequencies of some cores in a CPU package may be
14 * higher than for the other cores in the same package. In that case,
15 * better performance can be achieved by making the scheduler prefer
16 * to run tasks on the CPUs with higher max turbo frequencies.
17 *
18 * This file provides functions and data structures for enabling the
19 * scheduler to favor scheduling on cores can be boosted to a higher
20 * frequency under ITMT.
21 */
22
23#include <linux/sched.h>
24#include <linux/cpumask.h>
25#include <linux/cpuset.h>
26#include <asm/mutex.h>
27#include <linux/sched.h>
28#include <linux/sysctl.h>
29#include <linux/nodemask.h>
30
31static DEFINE_MUTEX(itmt_update_mutex);
32DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
33
34/* Boolean to track if system has ITMT capabilities */
35static bool __read_mostly sched_itmt_capable;
36
37/**
38 * sched_set_itmt_support() - Indicate platform supports ITMT
39 *
40 * This function is used by the OS to indicate to scheduler that the platform
41 * is capable of supporting the ITMT feature.
42 *
43 * The current scheme has the pstate driver detects if the system
44 * is ITMT capable and call sched_set_itmt_support.
45 *
46 * This must be done only after sched_set_itmt_core_prio
47 * has been called to set the cpus' priorities.
48 */
49void sched_set_itmt_support(void)
50{
51 mutex_lock(&itmt_update_mutex);
52
53 sched_itmt_capable = true;
54
55 mutex_unlock(&itmt_update_mutex);
56}
57
58/**
59 * sched_clear_itmt_support() - Revoke platform's support of ITMT
60 *
61 * This function is used by the OS to indicate that it has
62 * revoked the platform's support of ITMT feature.
63 *
64 */
65void sched_clear_itmt_support(void)
66{
67 mutex_lock(&itmt_update_mutex);
68
69 sched_itmt_capable = false;
70
71 mutex_unlock(&itmt_update_mutex);
72}
73
74int arch_asym_cpu_priority(int cpu)
75{
76 return per_cpu(sched_core_priority, cpu);
77}
78
79/**
80 * sched_set_itmt_core_prio() - Set CPU priority based on ITMT
81 * @prio: Priority of cpu core
82 * @core_cpu: The cpu number associated with the core
83 *
84 * The pstate driver will find out the max boost frequency
85 * and call this function to set a priority proportional
86 * to the max boost frequency. CPU with higher boost
87 * frequency will receive higher priority.
88 *
89 * No need to rebuild sched domain after updating
90 * the CPU priorities. The sched domains have no
91 * dependency on CPU priorities.
92 */
93void sched_set_itmt_core_prio(int prio, int core_cpu)
94{
95 int cpu, i = 1;
96
97 for_each_cpu(cpu, topology_sibling_cpumask(core_cpu)) {
98 int smt_prio;
99
100 /*
101 * Ensure that the siblings are moved to the end
102 * of the priority chain and only used when
103 * all other high priority cpus are out of capacity.
104 */
105 smt_prio = prio * smp_num_siblings / i;
106 per_cpu(sched_core_priority, cpu) = smt_prio;
107 i++;
108 }
109}