Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b04e1c1a authored by Junjie Wu's avatar Junjie Wu
Browse files

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: default avatarJunjie Wu <junjiew@codeaurora.org>
parent 29cf3c39
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -44,6 +44,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 */
@@ -122,12 +123,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);
@@ -137,7 +148,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 &&
@@ -157,8 +168,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;
@@ -358,6 +368,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))
@@ -1279,6 +1290,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);