aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Chen <tim.c.chen@linux.intel.com>2016-11-22 15:23:56 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-11-24 14:44:19 -0500
commitf9793e34952cda133caaa35738a4b46053331c96 (patch)
tree190366f26441bc5f2f06119cf8510c6dea2a909b
parent5e76b2ab36b40ca33023e78725bdc69eafd63134 (diff)
x86/sysctl: Add sysctl for ITMT scheduling feature
Intel Turbo Boost Max Technology 3.0 (ITMT) feature allows some cores to be boosted to higher turbo frequency than others. Add /proc/sys/kernel/sched_itmt_enabled so operator can enable/disable scheduling of tasks that favor cores with higher turbo boost frequency potential. By default, system that is ITMT capable and single socket has this feature turned on. It is more likely to be lightly loaded and operates in Turbo range. When there is a change in the ITMT scheduling operation desired, a rebuild of the sched domain is initiated so the scheduler can set up sched domains with appropriate flag to enable/disable ITMT scheduling operations. 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/07cc62426a28bad57b01ab16bb903a9c84fa5421.1479844244.git.tim.c.chen@linux.intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/include/asm/topology.h7
-rw-r--r--arch/x86/kernel/itmt.c108
2 files changed, 112 insertions, 3 deletions
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 8ace9511347c..4813df5c21f0 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -152,23 +152,26 @@ extern bool x86_topology_update;
152#include <asm/percpu.h> 152#include <asm/percpu.h>
153 153
154DECLARE_PER_CPU_READ_MOSTLY(int, sched_core_priority); 154DECLARE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
155extern unsigned int __read_mostly sysctl_sched_itmt_enabled;
155 156
156/* Interface to set priority of a cpu */ 157/* Interface to set priority of a cpu */
157void sched_set_itmt_core_prio(int prio, int core_cpu); 158void sched_set_itmt_core_prio(int prio, int core_cpu);
158 159
159/* Interface to notify scheduler that system supports ITMT */ 160/* Interface to notify scheduler that system supports ITMT */
160void sched_set_itmt_support(void); 161int sched_set_itmt_support(void);
161 162
162/* Interface to notify scheduler that system revokes ITMT support */ 163/* Interface to notify scheduler that system revokes ITMT support */
163void sched_clear_itmt_support(void); 164void sched_clear_itmt_support(void);
164 165
165#else /* CONFIG_SCHED_ITMT */ 166#else /* CONFIG_SCHED_ITMT */
166 167
168#define sysctl_sched_itmt_enabled 0
167static inline void sched_set_itmt_core_prio(int prio, int core_cpu) 169static inline void sched_set_itmt_core_prio(int prio, int core_cpu)
168{ 170{
169} 171}
170static inline void sched_set_itmt_support(void) 172static inline int sched_set_itmt_support(void)
171{ 173{
174 return 0;
172} 175}
173static inline void sched_clear_itmt_support(void) 176static inline void sched_clear_itmt_support(void)
174{ 177{
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
index 63c9b3e3509d..672fbf7df2a4 100644
--- a/arch/x86/kernel/itmt.c
+++ b/arch/x86/kernel/itmt.c
@@ -34,6 +34,68 @@ DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
34/* Boolean to track if system has ITMT capabilities */ 34/* Boolean to track if system has ITMT capabilities */
35static bool __read_mostly sched_itmt_capable; 35static bool __read_mostly sched_itmt_capable;
36 36
37/*
38 * Boolean to control whether we want to move processes to cpu capable
39 * of higher turbo frequency for cpus supporting Intel Turbo Boost Max
40 * Technology 3.0.
41 *
42 * It can be set via /proc/sys/kernel/sched_itmt_enabled
43 */
44unsigned int __read_mostly sysctl_sched_itmt_enabled;
45
46static int sched_itmt_update_handler(struct ctl_table *table, int write,
47 void __user *buffer, size_t *lenp,
48 loff_t *ppos)
49{
50 unsigned int old_sysctl;
51 int ret;
52
53 mutex_lock(&itmt_update_mutex);
54
55 if (!sched_itmt_capable) {
56 mutex_unlock(&itmt_update_mutex);
57 return -EINVAL;
58 }
59
60 old_sysctl = sysctl_sched_itmt_enabled;
61 ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
62
63 if (!ret && write && old_sysctl != sysctl_sched_itmt_enabled) {
64 x86_topology_update = true;
65 rebuild_sched_domains();
66 }
67
68 mutex_unlock(&itmt_update_mutex);
69
70 return ret;
71}
72
73static unsigned int zero;
74static unsigned int one = 1;
75static struct ctl_table itmt_kern_table[] = {
76 {
77 .procname = "sched_itmt_enabled",
78 .data = &sysctl_sched_itmt_enabled,
79 .maxlen = sizeof(unsigned int),
80 .mode = 0644,
81 .proc_handler = sched_itmt_update_handler,
82 .extra1 = &zero,
83 .extra2 = &one,
84 },
85 {}
86};
87
88static struct ctl_table itmt_root_table[] = {
89 {
90 .procname = "kernel",
91 .mode = 0555,
92 .child = itmt_kern_table,
93 },
94 {}
95};
96
97static struct ctl_table_header *itmt_sysctl_header;
98
37/** 99/**
38 * sched_set_itmt_support() - Indicate platform supports ITMT 100 * sched_set_itmt_support() - Indicate platform supports ITMT
39 * 101 *
@@ -45,14 +107,39 @@ static bool __read_mostly sched_itmt_capable;
45 * 107 *
46 * This must be done only after sched_set_itmt_core_prio 108 * This must be done only after sched_set_itmt_core_prio
47 * has been called to set the cpus' priorities. 109 * has been called to set the cpus' priorities.
110 * It must not be called with cpu hot plug lock
111 * held as we need to acquire the lock to rebuild sched domains
112 * later.
113 *
114 * Return: 0 on success
48 */ 115 */
49void sched_set_itmt_support(void) 116int sched_set_itmt_support(void)
50{ 117{
51 mutex_lock(&itmt_update_mutex); 118 mutex_lock(&itmt_update_mutex);
52 119
120 if (sched_itmt_capable) {
121 mutex_unlock(&itmt_update_mutex);
122 return 0;
123 }
124
125 itmt_sysctl_header = register_sysctl_table(itmt_root_table);
126 if (!itmt_sysctl_header) {
127 mutex_unlock(&itmt_update_mutex);
128 return -ENOMEM;
129 }
130
53 sched_itmt_capable = true; 131 sched_itmt_capable = true;
54 132
133 sysctl_sched_itmt_enabled = 1;
134
135 if (sysctl_sched_itmt_enabled) {
136 x86_topology_update = true;
137 rebuild_sched_domains();
138 }
139
55 mutex_unlock(&itmt_update_mutex); 140 mutex_unlock(&itmt_update_mutex);
141
142 return 0;
56} 143}
57 144
58/** 145/**
@@ -61,13 +148,32 @@ void sched_set_itmt_support(void)
61 * This function is used by the OS to indicate that it has 148 * This function is used by the OS to indicate that it has
62 * revoked the platform's support of ITMT feature. 149 * revoked the platform's support of ITMT feature.
63 * 150 *
151 * It must not be called with cpu hot plug lock
152 * held as we need to acquire the lock to rebuild sched domains
153 * later.
64 */ 154 */
65void sched_clear_itmt_support(void) 155void sched_clear_itmt_support(void)
66{ 156{
67 mutex_lock(&itmt_update_mutex); 157 mutex_lock(&itmt_update_mutex);
68 158
159 if (!sched_itmt_capable) {
160 mutex_unlock(&itmt_update_mutex);
161 return;
162 }
69 sched_itmt_capable = false; 163 sched_itmt_capable = false;
70 164
165 if (itmt_sysctl_header) {
166 unregister_sysctl_table(itmt_sysctl_header);
167 itmt_sysctl_header = NULL;
168 }
169
170 if (sysctl_sched_itmt_enabled) {
171 /* disable sched_itmt if we are no longer ITMT capable */
172 sysctl_sched_itmt_enabled = 0;
173 x86_topology_update = true;
174 rebuild_sched_domains();
175 }
176
71 mutex_unlock(&itmt_update_mutex); 177 mutex_unlock(&itmt_update_mutex);
72} 178}
73 179