Currently update_sampling_rate() runs over each online CPU and cancels/queues timers on all policy->cpus every time. This should be done just once for any cpu belonging to a policy.
Create a cpumask and keep on clearing it as and when we process policies, so that we don't have to traverse through all CPUs of the same policy.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org --- drivers/cpufreq/cpufreq_ondemand.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 9e0293c23285..6eac39124894 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -251,6 +251,7 @@ static void update_sampling_rate(struct dbs_data *dbs_data, struct cpufreq_policy *policy; struct cpu_common_dbs_info *shared; unsigned long next_sampling, appointed_at; + struct cpumask cpumask; int cpu;
od_tuners->sampling_rate = new_rate = max(new_rate, @@ -261,7 +262,9 @@ static void update_sampling_rate(struct dbs_data *dbs_data, */ mutex_lock(&od_dbs_cdata.mutex);
- for_each_online_cpu(cpu) { + cpumask_copy(&cpumask, cpu_online_mask); + + for_each_cpu(cpu, &cpumask) { dbs_info = &per_cpu(od_cpu_dbs_info, cpu); cdbs = &dbs_info->cdbs; shared = cdbs->shared; @@ -275,6 +278,9 @@ static void update_sampling_rate(struct dbs_data *dbs_data,
policy = shared->policy;
+ /* clear all CPUs of this policy */ + cpumask_andnot(&cpumask, &cpumask, policy->cpus); + /* * Update sampling rate for CPUs whose policy is governed by * dbs_data. In case of governor_per_policy, only a single @@ -284,6 +290,10 @@ static void update_sampling_rate(struct dbs_data *dbs_data, if (dbs_data != policy->governor_data) continue;
+ /* + * Checking this for any CPU should be fine, timers for all of + * them are scheduled together. + */ next_sampling = jiffies + usecs_to_jiffies(new_rate); appointed_at = dbs_info->cdbs.timer.expires;