cpufreq: interactive: Align timer windows for all CPUs

It's more advantageous to evaluate all CPUs at same time so that
interactive governor gets a complete picture of the load on
each CPU at a specific time. It could also reduce number of speed
changes made if there are many CPUs controlled by same policy. In
addition, waking up all CPUs at same time would allow the cluster
to go into a deeper sleep state when it's idle.

Change-Id: I6915050c5339ef1af106eb906ebe4b7c618061e2
Signed-off-by: Junjie Wu <junjiew@codeaurora.org>
This commit is contained in:
Junjie Wu 2014-04-28 15:11:47 -07:00 committed by David Keitel
parent 7b9f8f19a1
commit 6673fa0f98

View file

@ -42,6 +42,7 @@ struct cpufreq_interactive_cpuinfo {
u64 time_in_idle_timestamp;
u64 cputime_speedadj;
u64 cputime_speedadj_timestamp;
u64 last_evaluated_jiffy;
struct cpufreq_policy *policy;
struct cpufreq_frequency_table *freq_table;
spinlock_t target_freq_lock; /*protects target freq */
@ -144,12 +145,22 @@ static struct cpufreq_interactive_tunables *common_tunables;
static struct attribute_group *get_sysfs_attr(void);
/* Round to starting jiffy of next evaluation window */
static u64 round_to_nw_start(u64 jif,
struct cpufreq_interactive_tunables *tunables)
{
unsigned long step = usecs_to_jiffies(tunables->timer_rate);
do_div(jif, step);
return (jif + 1) * step;
}
static void cpufreq_interactive_timer_resched(
struct cpufreq_interactive_cpuinfo *pcpu)
{
struct cpufreq_interactive_tunables *tunables =
pcpu->policy->governor_data;
unsigned long expires;
u64 expires;
unsigned long flags;
spin_lock_irqsave(&pcpu->load_lock, flags);
@ -159,7 +170,7 @@ static void cpufreq_interactive_timer_resched(
tunables->io_is_busy);
pcpu->cputime_speedadj = 0;
pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
expires = jiffies + usecs_to_jiffies(tunables->timer_rate);
expires = round_to_nw_start(pcpu->last_evaluated_jiffy, tunables);
mod_timer_pinned(&pcpu->cpu_timer, expires);
if (tunables->timer_slack_val >= 0 &&
@ -179,8 +190,7 @@ static void cpufreq_interactive_timer_start(
struct cpufreq_interactive_tunables *tunables, int cpu)
{
struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
unsigned long expires = jiffies +
usecs_to_jiffies(tunables->timer_rate);
u64 expires = round_to_nw_start(pcpu->last_evaluated_jiffy, tunables);
unsigned long flags;
pcpu->cpu_timer.expires = expires;
@ -380,6 +390,7 @@ static void cpufreq_interactive_timer(unsigned long data)
now = update_load(data);
delta_time = (unsigned int)(now - pcpu->cputime_speedadj_timestamp);
cputime_speedadj = pcpu->cputime_speedadj;
pcpu->last_evaluated_jiffy = get_jiffies_64();
spin_unlock_irqrestore(&pcpu->load_lock, flags);
if (WARN_ON_ONCE(!delta_time))
@ -1275,6 +1286,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
down_write(&pcpu->enable_sem);
del_timer_sync(&pcpu->cpu_timer);
del_timer_sync(&pcpu->cpu_slack_timer);
pcpu->last_evaluated_jiffy = get_jiffies_64();
cpufreq_interactive_timer_start(tunables, j);
pcpu->governor_enabled = 1;
up_write(&pcpu->enable_sem);