ANDROID: sched/core: prevent timers on paused cpus

The pause feature is designed to keep CPUs idle as
much as possible.

When the timers migration feature is enabled (with
sysctl_timer_migration = 1 ) timer/hrtimer can be
migrated to other CPUs than the CPU currently
queueing the CPU. For example, a pinned kworker
runs on a paused CPU and queued the timer. The
other use case is an interrupt coming on paused CPU
and queueing the time.

Update the get nohz cpu path to use the active
and online masks to prevent paused cpus from
being woken up to queue a timer.

Bug: 161210528
Change-Id: I3707164ab6ea35cb6202b6c6b2018e1583c3e95c
Signed-off-by: Stephen Dickey <dickey@codeaurora.org>
This commit is contained in:
Stephen Dickey
2020-12-11 17:10:32 -08:00
committed by Quentin Perret
parent 321244d577
commit fe6f4b82d6

View File

@@ -671,7 +671,7 @@ int get_nohz_timer_target(void)
int i, cpu = smp_processor_id(), default_cpu = -1;
struct sched_domain *sd;
if (housekeeping_cpu(cpu, HK_FLAG_TIMER)) {
if (housekeeping_cpu(cpu, HK_FLAG_TIMER) && cpu_active(cpu)) {
if (!idle_cpu(cpu))
return cpu;
default_cpu = cpu;
@@ -691,8 +691,25 @@ int get_nohz_timer_target(void)
}
}
if (default_cpu == -1)
default_cpu = housekeeping_any_cpu(HK_FLAG_TIMER);
if (default_cpu == -1) {
for_each_cpu_and(i, cpu_active_mask,
housekeeping_cpumask(HK_FLAG_TIMER)) {
if (cpu == i)
continue;
if (!idle_cpu(i)) {
cpu = i;
goto unlock;
}
}
/* no active, not-idle, housekpeeing CPU found. */
default_cpu = cpumask_any(cpu_active_mask);
if (unlikely(default_cpu >= nr_cpu_ids))
goto unlock;
}
cpu = default_cpu;
unlock:
rcu_read_unlock();