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

Commit 2cd7cc79 authored by Junjie Wu's avatar Junjie Wu
Browse files

cpufreq: interactive: Use del_timer/add_timer_on to rearm timers



Replace mod_timer_pinned() with del_timer(), add_timer_on().
mod_timer_pinned() always adds timer onto current CPU. Interactive
governor expects each CPU's timers to be running on the same CPU.
If cpufreq_interactive_timer_resched() is called from another CPU,
the timer will be armed on the wrong CPU.

Replacing mod_timer_pinned() with del_timer() and add_timer_on()
guarantees timers are still run on the right CPU even if another
CPU reschedules the timer. This would provide more flexibility
for future changes.

Change-Id: I3a10be37632afc0ea4e0cc9c86323b9783b216b1
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
parent 53994155
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -133,9 +133,9 @@ static u64 round_to_nw_start(u64 jif,
	return (jif + 1) * step;
}

static void cpufreq_interactive_timer_resched(
	struct cpufreq_interactive_cpuinfo *pcpu)
static void cpufreq_interactive_timer_resched(unsigned long cpu)
{
	struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu);
	struct cpufreq_interactive_tunables *tunables =
		pcpu->policy->governor_data;
	u64 expires;
@@ -149,12 +149,16 @@ static void cpufreq_interactive_timer_resched(
	pcpu->cputime_speedadj = 0;
	pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
	expires = round_to_nw_start(pcpu->last_evaluated_jiffy, tunables);
	mod_timer_pinned(&pcpu->cpu_timer, expires);
	del_timer(&pcpu->cpu_timer);
	pcpu->cpu_timer.expires = expires;
	add_timer_on(&pcpu->cpu_timer, cpu);

	if (tunables->timer_slack_val >= 0 &&
	    pcpu->target_freq > pcpu->policy->min) {
		expires += usecs_to_jiffies(tunables->timer_slack_val);
		mod_timer_pinned(&pcpu->cpu_slack_timer, expires);
		del_timer(&pcpu->cpu_slack_timer);
		pcpu->cpu_slack_timer.expires = expires;
		add_timer_on(&pcpu->cpu_slack_timer, cpu);
	}

	spin_unlock_irqrestore(&pcpu->load_lock, flags);
@@ -171,6 +175,7 @@ static void cpufreq_interactive_timer_start(
	u64 expires = round_to_nw_start(pcpu->last_evaluated_jiffy, tunables);
	unsigned long flags;

	spin_lock_irqsave(&pcpu->load_lock, flags);
	pcpu->cpu_timer.expires = expires;
	add_timer_on(&pcpu->cpu_timer, cpu);
	if (tunables->timer_slack_val >= 0 &&
@@ -180,7 +185,6 @@ static void cpufreq_interactive_timer_start(
		add_timer_on(&pcpu->cpu_slack_timer, cpu);
	}

	spin_lock_irqsave(&pcpu->load_lock, flags);
	pcpu->time_in_idle =
		get_cpu_idle_time(cpu, &pcpu->time_in_idle_timestamp,
				  tunables->io_is_busy);
@@ -471,7 +475,7 @@ rearm_if_notmax:

rearm:
	if (!timer_pending(&pcpu->cpu_timer))
		cpufreq_interactive_timer_resched(pcpu);
		cpufreq_interactive_timer_resched(data);

exit:
	up_read(&pcpu->enable_sem);
@@ -504,7 +508,7 @@ static void cpufreq_interactive_idle_start(void)
		 */
		if (!pending) {
			pcpu->last_evaluated_jiffy = get_jiffies_64();
			cpufreq_interactive_timer_resched(pcpu);
			cpufreq_interactive_timer_resched(smp_processor_id());
		}
	}

@@ -525,7 +529,7 @@ static void cpufreq_interactive_idle_end(void)

	/* Arm the timer for 1-2 ticks later if not already. */
	if (!timer_pending(&pcpu->cpu_timer)) {
		cpufreq_interactive_timer_resched(pcpu);
		cpufreq_interactive_timer_resched(smp_processor_id());
	} else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) {
		del_timer(&pcpu->cpu_timer);
		del_timer(&pcpu->cpu_slack_timer);
@@ -1358,7 +1362,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);
				cpufreq_interactive_timer_start(tunables, j);
				cpufreq_interactive_timer_resched(j);
				up_write(&pcpu->enable_sem);
			}