aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-03-31 11:42:15 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-03-31 11:42:15 -0400
commitbb6ab52f2befe1fb29ac198f27d8a6aadf510f81 (patch)
treee1fd997a070d0a2f53e0be2a520d4287befb898c
parent539a4c4247c2697d291a8fb02c485ccd7cf34f05 (diff)
intel_pstate: Do not set utilization update hook too early
The utilization update hook in the intel_pstate driver is set too early, as it only should be set after the policy has been fully initialized by the core. That may cause intel_pstate_update_util() to use incorrect data and put the CPUs into incorrect P-states as a result. To prevent that from happening, make intel_pstate_set_policy() set the utilization update hook instead of intel_pstate_init_cpu() so intel_pstate_update_util() only runs when all things have been initialized as appropriate. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/intel_pstate.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 4b644526fd59..81057e48c4de 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1103,7 +1103,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
1103 intel_pstate_sample(cpu, 0); 1103 intel_pstate_sample(cpu, 0);
1104 1104
1105 cpu->update_util.func = intel_pstate_update_util; 1105 cpu->update_util.func = intel_pstate_update_util;
1106 cpufreq_set_update_util_data(cpunum, &cpu->update_util);
1107 1106
1108 pr_debug("intel_pstate: controlling: cpu %d\n", cpunum); 1107 pr_debug("intel_pstate: controlling: cpu %d\n", cpunum);
1109 1108
@@ -1122,18 +1121,29 @@ static unsigned int intel_pstate_get(unsigned int cpu_num)
1122 return get_avg_frequency(cpu); 1121 return get_avg_frequency(cpu);
1123} 1122}
1124 1123
1124static void intel_pstate_set_update_util_hook(unsigned int cpu)
1125{
1126 cpufreq_set_update_util_data(cpu, &all_cpu_data[cpu]->update_util);
1127}
1128
1129static void intel_pstate_clear_update_util_hook(unsigned int cpu)
1130{
1131 cpufreq_set_update_util_data(cpu, NULL);
1132 synchronize_sched();
1133}
1134
1125static int intel_pstate_set_policy(struct cpufreq_policy *policy) 1135static int intel_pstate_set_policy(struct cpufreq_policy *policy)
1126{ 1136{
1127 if (!policy->cpuinfo.max_freq) 1137 if (!policy->cpuinfo.max_freq)
1128 return -ENODEV; 1138 return -ENODEV;
1129 1139
1140 intel_pstate_clear_update_util_hook(policy->cpu);
1141
1130 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE && 1142 if (policy->policy == CPUFREQ_POLICY_PERFORMANCE &&
1131 policy->max >= policy->cpuinfo.max_freq) { 1143 policy->max >= policy->cpuinfo.max_freq) {
1132 pr_debug("intel_pstate: set performance\n"); 1144 pr_debug("intel_pstate: set performance\n");
1133 limits = &performance_limits; 1145 limits = &performance_limits;
1134 if (hwp_active) 1146 goto out;
1135 intel_pstate_hwp_set(policy->cpus);
1136 return 0;
1137 } 1147 }
1138 1148
1139 pr_debug("intel_pstate: set powersave\n"); 1149 pr_debug("intel_pstate: set powersave\n");
@@ -1163,6 +1173,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
1163 limits->max_perf = div_fp(int_tofp(limits->max_perf_pct), 1173 limits->max_perf = div_fp(int_tofp(limits->max_perf_pct),
1164 int_tofp(100)); 1174 int_tofp(100));
1165 1175
1176 out:
1177 intel_pstate_set_update_util_hook(policy->cpu);
1178
1166 if (hwp_active) 1179 if (hwp_active)
1167 intel_pstate_hwp_set(policy->cpus); 1180 intel_pstate_hwp_set(policy->cpus);
1168 1181
@@ -1187,8 +1200,7 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
1187 1200
1188 pr_debug("intel_pstate: CPU %d exiting\n", cpu_num); 1201 pr_debug("intel_pstate: CPU %d exiting\n", cpu_num);
1189 1202
1190 cpufreq_set_update_util_data(cpu_num, NULL); 1203 intel_pstate_clear_update_util_hook(cpu_num);
1191 synchronize_sched();
1192 1204
1193 if (hwp_active) 1205 if (hwp_active)
1194 return; 1206 return;
@@ -1455,8 +1467,7 @@ out:
1455 get_online_cpus(); 1467 get_online_cpus();
1456 for_each_online_cpu(cpu) { 1468 for_each_online_cpu(cpu) {
1457 if (all_cpu_data[cpu]) { 1469 if (all_cpu_data[cpu]) {
1458 cpufreq_set_update_util_data(cpu, NULL); 1470 intel_pstate_clear_update_util_hook(cpu);
1459 synchronize_sched();
1460 kfree(all_cpu_data[cpu]); 1471 kfree(all_cpu_data[cpu]);
1461 } 1472 }
1462 } 1473 }