diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-11-18 18:20:42 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-11-18 18:20:42 -0500 |
commit | 6ee11e413c495390dacabd96ad462eea9de9dfbd (patch) | |
tree | 40fcd53a0106cb0e86d51ccc4cd378cf1b7406cf | |
parent | 799281a3c481a738801bf17e3079a6f91df56cd3 (diff) |
Revert "cpufreq: intel_pstate: Use ACPI perf configuration"
Revert commit 37afb0003242 (cpufreq: intel_pstate: Use ACPI perf
configuration) that is reported to cause a regression to happen
on a system where invalid data are returned by the ACPI _PSS object.
Since that commit makes assumptions regarding the _PSS output
correctness that may turn out to be overly optimistic in general,
there is a concern that it may introduce regression on more
systems, so it's better to revert it now and we'll revisit the
underlying issue in the next cycle with a more robust solution.
Conflicts:
drivers/cpufreq/intel_pstate.c
Fixes: 37afb0003242 (cpufreq: intel_pstate: Use ACPI perf configuration)
Reported-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/cpufreq/Kconfig.x86 | 1 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 171 |
2 files changed, 1 insertions, 171 deletions
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index adbd1de1cea5..c59bdcb83217 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 | |||
@@ -5,7 +5,6 @@ | |||
5 | config X86_INTEL_PSTATE | 5 | config X86_INTEL_PSTATE |
6 | bool "Intel P state control" | 6 | bool "Intel P state control" |
7 | depends on X86 | 7 | depends on X86 |
8 | select ACPI_PROCESSOR if ACPI | ||
9 | help | 8 | help |
10 | This driver provides a P state for Intel core processors. | 9 | This driver provides a P state for Intel core processors. |
11 | The driver implements an internal governor and will become | 10 | The driver implements an internal governor and will become |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index d444000ce148..ef05944d8b16 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -34,10 +34,6 @@ | |||
34 | #include <asm/cpu_device_id.h> | 34 | #include <asm/cpu_device_id.h> |
35 | #include <asm/cpufeature.h> | 35 | #include <asm/cpufeature.h> |
36 | 36 | ||
37 | #if IS_ENABLED(CONFIG_ACPI) | ||
38 | #include <acpi/processor.h> | ||
39 | #endif | ||
40 | |||
41 | #define BYT_RATIOS 0x66a | 37 | #define BYT_RATIOS 0x66a |
42 | #define BYT_VIDS 0x66b | 38 | #define BYT_VIDS 0x66b |
43 | #define BYT_TURBO_RATIOS 0x66c | 39 | #define BYT_TURBO_RATIOS 0x66c |
@@ -117,9 +113,6 @@ struct cpudata { | |||
117 | u64 prev_mperf; | 113 | u64 prev_mperf; |
118 | u64 prev_tsc; | 114 | u64 prev_tsc; |
119 | struct sample sample; | 115 | struct sample sample; |
120 | #if IS_ENABLED(CONFIG_ACPI) | ||
121 | struct acpi_processor_performance acpi_perf_data; | ||
122 | #endif | ||
123 | }; | 116 | }; |
124 | 117 | ||
125 | static struct cpudata **all_cpu_data; | 118 | static struct cpudata **all_cpu_data; |
@@ -150,7 +143,6 @@ struct cpu_defaults { | |||
150 | static struct pstate_adjust_policy pid_params; | 143 | static struct pstate_adjust_policy pid_params; |
151 | static struct pstate_funcs pstate_funcs; | 144 | static struct pstate_funcs pstate_funcs; |
152 | static int hwp_active; | 145 | static int hwp_active; |
153 | static int no_acpi_perf; | ||
154 | 146 | ||
155 | struct perf_limits { | 147 | struct perf_limits { |
156 | int no_turbo; | 148 | int no_turbo; |
@@ -197,153 +189,6 @@ static struct perf_limits *limits = &performance_limits; | |||
197 | static struct perf_limits *limits = &powersave_limits; | 189 | static struct perf_limits *limits = &powersave_limits; |
198 | #endif | 190 | #endif |
199 | 191 | ||
200 | #if IS_ENABLED(CONFIG_ACPI) | ||
201 | /* | ||
202 | * The max target pstate ratio is a 8 bit value in both PLATFORM_INFO MSR and | ||
203 | * in TURBO_RATIO_LIMIT MSR, which pstate driver stores in max_pstate and | ||
204 | * max_turbo_pstate fields. The PERF_CTL MSR contains 16 bit value for P state | ||
205 | * ratio, out of it only high 8 bits are used. For example 0x1700 is setting | ||
206 | * target ratio 0x17. The _PSS control value stores in a format which can be | ||
207 | * directly written to PERF_CTL MSR. But in intel_pstate driver this shift | ||
208 | * occurs during write to PERF_CTL (E.g. for cores core_set_pstate()). | ||
209 | * This function converts the _PSS control value to intel pstate driver format | ||
210 | * for comparison and assignment. | ||
211 | */ | ||
212 | static int convert_to_native_pstate_format(struct cpudata *cpu, int index) | ||
213 | { | ||
214 | return cpu->acpi_perf_data.states[index].control >> 8; | ||
215 | } | ||
216 | |||
217 | static int intel_pstate_init_perf_limits(struct cpufreq_policy *policy) | ||
218 | { | ||
219 | struct cpudata *cpu; | ||
220 | int ret; | ||
221 | bool turbo_absent = false; | ||
222 | int max_pstate_index; | ||
223 | int min_pss_ctl, max_pss_ctl, turbo_pss_ctl; | ||
224 | int i; | ||
225 | |||
226 | cpu = all_cpu_data[policy->cpu]; | ||
227 | |||
228 | pr_debug("intel_pstate: default limits 0x%x 0x%x 0x%x\n", | ||
229 | cpu->pstate.min_pstate, cpu->pstate.max_pstate, | ||
230 | cpu->pstate.turbo_pstate); | ||
231 | |||
232 | if (!cpu->acpi_perf_data.shared_cpu_map && | ||
233 | zalloc_cpumask_var_node(&cpu->acpi_perf_data.shared_cpu_map, | ||
234 | GFP_KERNEL, cpu_to_node(policy->cpu))) { | ||
235 | return -ENOMEM; | ||
236 | } | ||
237 | |||
238 | ret = acpi_processor_register_performance(&cpu->acpi_perf_data, | ||
239 | policy->cpu); | ||
240 | if (ret) | ||
241 | return ret; | ||
242 | |||
243 | /* | ||
244 | * Check if the control value in _PSS is for PERF_CTL MSR, which should | ||
245 | * guarantee that the states returned by it map to the states in our | ||
246 | * list directly. | ||
247 | */ | ||
248 | if (cpu->acpi_perf_data.control_register.space_id != | ||
249 | ACPI_ADR_SPACE_FIXED_HARDWARE) | ||
250 | return -EIO; | ||
251 | |||
252 | pr_debug("intel_pstate: CPU%u - ACPI _PSS perf data\n", policy->cpu); | ||
253 | for (i = 0; i < cpu->acpi_perf_data.state_count; i++) | ||
254 | pr_debug(" %cP%d: %u MHz, %u mW, 0x%x\n", | ||
255 | (i == cpu->acpi_perf_data.state ? '*' : ' '), i, | ||
256 | (u32) cpu->acpi_perf_data.states[i].core_frequency, | ||
257 | (u32) cpu->acpi_perf_data.states[i].power, | ||
258 | (u32) cpu->acpi_perf_data.states[i].control); | ||
259 | |||
260 | /* | ||
261 | * If there is only one entry _PSS, simply ignore _PSS and continue as | ||
262 | * usual without taking _PSS into account | ||
263 | */ | ||
264 | if (cpu->acpi_perf_data.state_count < 2) | ||
265 | return 0; | ||
266 | |||
267 | turbo_pss_ctl = convert_to_native_pstate_format(cpu, 0); | ||
268 | min_pss_ctl = convert_to_native_pstate_format(cpu, | ||
269 | cpu->acpi_perf_data.state_count - 1); | ||
270 | /* Check if there is a turbo freq in _PSS */ | ||
271 | if (turbo_pss_ctl <= cpu->pstate.max_pstate && | ||
272 | turbo_pss_ctl > cpu->pstate.min_pstate) { | ||
273 | pr_debug("intel_pstate: no turbo range exists in _PSS\n"); | ||
274 | limits->no_turbo = limits->turbo_disabled = 1; | ||
275 | cpu->pstate.turbo_pstate = cpu->pstate.max_pstate; | ||
276 | turbo_absent = true; | ||
277 | } | ||
278 | |||
279 | /* Check if the max non turbo p state < Intel P state max */ | ||
280 | max_pstate_index = turbo_absent ? 0 : 1; | ||
281 | max_pss_ctl = convert_to_native_pstate_format(cpu, max_pstate_index); | ||
282 | if (max_pss_ctl < cpu->pstate.max_pstate && | ||
283 | max_pss_ctl > cpu->pstate.min_pstate) | ||
284 | cpu->pstate.max_pstate = max_pss_ctl; | ||
285 | |||
286 | /* check If min perf > Intel P State min */ | ||
287 | if (min_pss_ctl > cpu->pstate.min_pstate && | ||
288 | min_pss_ctl < cpu->pstate.max_pstate) { | ||
289 | cpu->pstate.min_pstate = min_pss_ctl; | ||
290 | policy->cpuinfo.min_freq = min_pss_ctl * cpu->pstate.scaling; | ||
291 | } | ||
292 | |||
293 | if (turbo_absent) | ||
294 | policy->cpuinfo.max_freq = cpu->pstate.max_pstate * | ||
295 | cpu->pstate.scaling; | ||
296 | else { | ||
297 | policy->cpuinfo.max_freq = cpu->pstate.turbo_pstate * | ||
298 | cpu->pstate.scaling; | ||
299 | /* | ||
300 | * The _PSS table doesn't contain whole turbo frequency range. | ||
301 | * This just contains +1 MHZ above the max non turbo frequency, | ||
302 | * with control value corresponding to max turbo ratio. But | ||
303 | * when cpufreq set policy is called, it will call with this | ||
304 | * max frequency, which will cause a reduced performance as | ||
305 | * this driver uses real max turbo frequency as the max | ||
306 | * frequeny. So correct this frequency in _PSS table to | ||
307 | * correct max turbo frequency based on the turbo ratio. | ||
308 | * Also need to convert to MHz as _PSS freq is in MHz. | ||
309 | */ | ||
310 | cpu->acpi_perf_data.states[0].core_frequency = | ||
311 | turbo_pss_ctl * 100; | ||
312 | } | ||
313 | |||
314 | pr_debug("intel_pstate: Updated limits using _PSS 0x%x 0x%x 0x%x\n", | ||
315 | cpu->pstate.min_pstate, cpu->pstate.max_pstate, | ||
316 | cpu->pstate.turbo_pstate); | ||
317 | pr_debug("intel_pstate: policy max_freq=%d Khz min_freq = %d KHz\n", | ||
318 | policy->cpuinfo.max_freq, policy->cpuinfo.min_freq); | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int intel_pstate_exit_perf_limits(struct cpufreq_policy *policy) | ||
324 | { | ||
325 | struct cpudata *cpu; | ||
326 | |||
327 | if (!no_acpi_perf) | ||
328 | return 0; | ||
329 | |||
330 | cpu = all_cpu_data[policy->cpu]; | ||
331 | acpi_processor_unregister_performance(policy->cpu); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | #else | ||
336 | static int intel_pstate_init_perf_limits(struct cpufreq_policy *policy) | ||
337 | { | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int intel_pstate_exit_perf_limits(struct cpufreq_policy *policy) | ||
342 | { | ||
343 | return 0; | ||
344 | } | ||
345 | #endif | ||
346 | |||
347 | static inline void pid_reset(struct _pid *pid, int setpoint, int busy, | 192 | static inline void pid_reset(struct _pid *pid, int setpoint, int busy, |
348 | int deadband, int integral) { | 193 | int deadband, int integral) { |
349 | pid->setpoint = setpoint; | 194 | pid->setpoint = setpoint; |
@@ -1303,30 +1148,18 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy) | |||
1303 | policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling; | 1148 | policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling; |
1304 | policy->cpuinfo.max_freq = | 1149 | policy->cpuinfo.max_freq = |
1305 | cpu->pstate.turbo_pstate * cpu->pstate.scaling; | 1150 | cpu->pstate.turbo_pstate * cpu->pstate.scaling; |
1306 | if (!no_acpi_perf) | ||
1307 | intel_pstate_init_perf_limits(policy); | ||
1308 | /* | ||
1309 | * If there is no acpi perf data or error, we ignore and use Intel P | ||
1310 | * state calculated limits, So this is not fatal error. | ||
1311 | */ | ||
1312 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 1151 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
1313 | cpumask_set_cpu(policy->cpu, policy->cpus); | 1152 | cpumask_set_cpu(policy->cpu, policy->cpus); |
1314 | 1153 | ||
1315 | return 0; | 1154 | return 0; |
1316 | } | 1155 | } |
1317 | 1156 | ||
1318 | static int intel_pstate_cpu_exit(struct cpufreq_policy *policy) | ||
1319 | { | ||
1320 | return intel_pstate_exit_perf_limits(policy); | ||
1321 | } | ||
1322 | |||
1323 | static struct cpufreq_driver intel_pstate_driver = { | 1157 | static struct cpufreq_driver intel_pstate_driver = { |
1324 | .flags = CPUFREQ_CONST_LOOPS, | 1158 | .flags = CPUFREQ_CONST_LOOPS, |
1325 | .verify = intel_pstate_verify_policy, | 1159 | .verify = intel_pstate_verify_policy, |
1326 | .setpolicy = intel_pstate_set_policy, | 1160 | .setpolicy = intel_pstate_set_policy, |
1327 | .get = intel_pstate_get, | 1161 | .get = intel_pstate_get, |
1328 | .init = intel_pstate_cpu_init, | 1162 | .init = intel_pstate_cpu_init, |
1329 | .exit = intel_pstate_cpu_exit, | ||
1330 | .stop_cpu = intel_pstate_stop_cpu, | 1163 | .stop_cpu = intel_pstate_stop_cpu, |
1331 | .name = "intel_pstate", | 1164 | .name = "intel_pstate", |
1332 | }; | 1165 | }; |
@@ -1368,6 +1201,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs) | |||
1368 | } | 1201 | } |
1369 | 1202 | ||
1370 | #if IS_ENABLED(CONFIG_ACPI) | 1203 | #if IS_ENABLED(CONFIG_ACPI) |
1204 | #include <acpi/processor.h> | ||
1371 | 1205 | ||
1372 | static bool intel_pstate_no_acpi_pss(void) | 1206 | static bool intel_pstate_no_acpi_pss(void) |
1373 | { | 1207 | { |
@@ -1563,9 +1397,6 @@ static int __init intel_pstate_setup(char *str) | |||
1563 | force_load = 1; | 1397 | force_load = 1; |
1564 | if (!strcmp(str, "hwp_only")) | 1398 | if (!strcmp(str, "hwp_only")) |
1565 | hwp_only = 1; | 1399 | hwp_only = 1; |
1566 | if (!strcmp(str, "no_acpi")) | ||
1567 | no_acpi_perf = 1; | ||
1568 | |||
1569 | return 0; | 1400 | return 0; |
1570 | } | 1401 | } |
1571 | early_param("intel_pstate", intel_pstate_setup); | 1402 | early_param("intel_pstate", intel_pstate_setup); |