diff options
| author | Junjie Wu <junjiew@codeaurora.org> | 2015-05-26 17:54:38 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:03:24 -0700 |
| commit | e5e613be759829935ef7ae26324d3aea64a087b3 (patch) | |
| tree | 40a2860b950ce7dd4581144f271fd84f348d8b93 | |
| parent | 7ebf7c3881f22f25ed64724c06d44d5142b3912b (diff) | |
cpufreq: interactive: Use sched_get_cpus_busy() to query busy time
sched_get_cpus_busy() provides a snapshot of all CPUs' busy time
information for the set of CPUs being queried. This avoids race
condition due to migration when CPU load is queried one by one.
Change-Id: I6afdfa74ff9f3ef616872df4e2c3bb04f6233c3f
Signed-off-by: Junjie Wu <junjiew@codeaurora.org>
| -rw-r--r-- | drivers/cpufreq/cpufreq_interactive.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 31151f0df5b1..7a262974b128 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -52,6 +52,7 @@ struct cpufreq_interactive_policyinfo { bool reject_notification; int governor_enabled; struct cpufreq_interactive_tunables *cached_tunables; + unsigned long *cpu_busy_times; }; /* Protected by per-policy load_lock */ @@ -442,7 +443,7 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif) unsigned int index; unsigned long flags; unsigned long max_cpu; - int i; + int i, fcpu; struct cpufreq_govinfo govinfo; if (!down_read_trylock(&ppol->enable_sem)) @@ -450,16 +451,20 @@ static void __cpufreq_interactive_timer(unsigned long data, bool is_notif) if (!ppol->governor_enabled) goto exit; + fcpu = cpumask_first(ppol->policy->related_cpus); now = ktime_to_us(ktime_get()); spin_lock_irqsave(&ppol->load_lock, flags); ppol->last_evaluated_jiffy = get_jiffies_64(); + if (tunables->use_sched_load) + sched_get_cpus_busy(ppol->cpu_busy_times, + ppol->policy->related_cpus); max_cpu = cpumask_first(ppol->policy->cpus); for_each_cpu(i, ppol->policy->cpus) { pcpu = &per_cpu(cpuinfo, i); if (tunables->use_sched_load) { - cputime_speedadj = (u64)sched_get_busy(i) * - ppol->policy->cpuinfo.max_freq; + cputime_speedadj = (u64)ppol->cpu_busy_times[i - fcpu] + * ppol->policy->cpuinfo.max_freq; do_div(cputime_speedadj, tunables->timer_rate); } else { now = update_load(i); @@ -1467,6 +1472,7 @@ static struct cpufreq_interactive_policyinfo *get_policyinfo( struct cpufreq_interactive_policyinfo *ppol = per_cpu(polinfo, policy->cpu); int i; + unsigned long *busy; /* polinfo already allocated for policy, return */ if (ppol) @@ -1476,6 +1482,14 @@ static struct cpufreq_interactive_policyinfo *get_policyinfo( if (!ppol) return ERR_PTR(-ENOMEM); + busy = kcalloc(cpumask_weight(policy->related_cpus), sizeof(*busy), + GFP_KERNEL); + if (!busy) { + kfree(ppol); + return ERR_PTR(-ENOMEM); + } + ppol->cpu_busy_times = busy; + init_timer_deferrable(&ppol->policy_timer); ppol->policy_timer.function = cpufreq_interactive_timer; init_timer(&ppol->policy_slack_timer); @@ -1502,6 +1516,7 @@ static void free_policyinfo(int cpu) if (per_cpu(polinfo, j) == ppol) per_cpu(polinfo, cpu) = NULL; kfree(ppol->cached_tunables); + kfree(ppol->cpu_busy_times); kfree(ppol); } |
