cpufreq: Retain only online cpus in managed_policy->cpus
cpufreq's handling of cpu online event can incorrectly initialize
managed_policy->cpus to include offline cpus. This causes cpufreq
governors to include offline cpus in their idle time computation, which
causes frequency to shoot up beyond normal levels (on systems where 2 or
more cpus need to be synchronized wrt frequency change).
This frequency shootup was not seen prior to commit 21111be8 which
changed idle time accounting for offline cpus. Prior to commit 21111be8,
idle time statistics for offline cpus would include their offline time
as well. Post commit 21111be8, offline time is not included in a cpu's
idle time statistics.
As a result, ondemand (or other cpufreq) governors would see unchanged
idle time for offline cpus, causing them to interpret those (offline)
cpus as 100% busy, which is wrong.
This patch fixes the issue by modifying cpufreq's hotplug handling to
retain only online cpus in managed_policy->cpus field. cpufreq governors
would then skip such offline cpus from idle time calculations.
Change-Id: Id2eba8c0ec3367609369b2e42a4e1386ff2e7ab5
Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org>
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index be71347..3d5614b 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -787,6 +787,8 @@
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpumask_copy(managed_policy->cpus, policy->cpus);
+ cpumask_and(managed_policy->cpus,
+ managed_policy->cpus, cpu_online_mask);
per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);