aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>2006-10-03 15:38:45 -0400
committerDave Jones <davej@redhat.com>2006-10-15 19:57:11 -0400
commitdfde5d62ed9b28b0bda676c16e8cb635df244ef2 (patch)
tree12c690189fcc7155389860beae554199456b7d3e /drivers
parenta6f6e6e6ab464c9d1dff66570b78be2f66d8ba3d (diff)
[CPUFREQ][8/8] acpi-cpufreq: Add support for freq feedback from hardware
Enable ondemand governor and acpi-cpufreq to use IA32_APERF and IA32_MPERF MSR to get active frequency feedback for the last sampling interval. This will make ondemand take right frequency decisions when hardware coordination of frequency is going on. Without APERF/MPERF, ondemand can take wrong decision at times due to underlying hardware coordination or TM2. Example: * CPU 0 and CPU 1 are hardware cooridnated. * CPU 1 running at highest frequency. * CPU 0 was running at highest freq. Now ondemand reduces it to some intermediate frequency based on utilization. * Due to underlying hardware coordination with other CPU 1, CPU 0 continues to run at highest frequency (as long as other CPU is at highest). * When ondemand samples CPU 0 again next time, without actual frequency feedback from APERF/MPERF, it will think that previous frequency change was successful and can go to wrong target frequency. This is because it thinks that utilization it has got this sampling interval is when running at intermediate frequency, rather than actual highest frequency. More information about IA32_APERF IA32_MPERF MSR: Refer to IA-32 IntelĀ® Architecture Software Developer's Manual at http://developer.intel.com Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/cpufreq.c20
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c9
2 files changed, 28 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 86e69b7f9122..56c433e64d58 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1274,6 +1274,26 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
1274} 1274}
1275EXPORT_SYMBOL_GPL(cpufreq_driver_target); 1275EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1276 1276
1277int cpufreq_driver_getavg(struct cpufreq_policy *policy)
1278{
1279 int ret = 0;
1280
1281 policy = cpufreq_cpu_get(policy->cpu);
1282 if (!policy)
1283 return -EINVAL;
1284
1285 mutex_lock(&policy->lock);
1286
1287 if (cpu_online(policy->cpu) && cpufreq_driver->getavg)
1288 ret = cpufreq_driver->getavg(policy->cpu);
1289
1290 mutex_unlock(&policy->lock);
1291
1292 cpufreq_cpu_put(policy);
1293 return ret;
1294}
1295EXPORT_SYMBOL_GPL(cpufreq_driver_getavg);
1296
1277/* 1297/*
1278 * Locking: Must be called with the lock_cpu_hotplug() lock held 1298 * Locking: Must be called with the lock_cpu_hotplug() lock held
1279 * when "event" is CPUFREQ_GOV_LIMITS 1299 * when "event" is CPUFREQ_GOV_LIMITS
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index bf8aa45d4f01..291cfe9400a1 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -393,8 +393,15 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
393 * policy. To be safe, we focus 10 points under the threshold. 393 * policy. To be safe, we focus 10 points under the threshold.
394 */ 394 */
395 if (load < (dbs_tuners_ins.up_threshold - 10)) { 395 if (load < (dbs_tuners_ins.up_threshold - 10)) {
396 unsigned int freq_next = (policy->cur * load) / 396 unsigned int freq_next, freq_cur;
397
398 freq_cur = cpufreq_driver_getavg(policy);
399 if (!freq_cur)
400 freq_cur = policy->cur;
401
402 freq_next = (freq_cur * load) /
397 (dbs_tuners_ins.up_threshold - 10); 403 (dbs_tuners_ins.up_threshold - 10);
404
398 if (!dbs_tuners_ins.powersave_bias) { 405 if (!dbs_tuners_ins.powersave_bias) {
399 __cpufreq_driver_target(policy, freq_next, 406 __cpufreq_driver_target(policy, freq_next,
400 CPUFREQ_RELATION_L); 407 CPUFREQ_RELATION_L);