From 0479c6b6d731af2ea81c866a52d6475bf94c8469 Mon Sep 17 00:00:00 2001 From: Raghavendra Kakarla Date: Sun, 18 Oct 2020 00:51:47 +0530 Subject: [PATCH] cpuidle: lpm-levels: Store per core next hrtimer wakeup Currently next wakeup is stored per lpm_cpu domain which have only last cpu's next wakeup. This overrides early wakeups of previous cpus in the same domain. Fix this by using per cpu next hrtimer. Change-Id: Ic99e82cbb2a1b4eb6fa578b40045fab2bb22a557 Signed-off-by: Raghavendra Kakarla --- drivers/cpuidle/lpm-levels.c | 9 +++++---- drivers/cpuidle/lpm-levels.h | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c index 492c4e381262..d094202bbaff 100644 --- a/drivers/cpuidle/lpm-levels.c +++ b/drivers/cpuidle/lpm-levels.c @@ -101,6 +101,7 @@ struct ipi_history { ktime_t cpu_idle_resched_ts; }; +static DEFINE_PER_CPU(ktime_t, next_hrtimer); static DEFINE_PER_CPU(struct lpm_history, hist); static DEFINE_PER_CPU(struct ipi_history, cpu_ipi_history); static DEFINE_PER_CPU(struct lpm_cpu*, cpu_lpm); @@ -264,7 +265,7 @@ static uint32_t get_next_event(struct lpm_cpu *cpu) return 0; for_each_cpu(next_cpu, &cpu_lpm_mask) { - ktime_t next_event_c = per_cpu(cpu_lpm, next_cpu)->next_hrtimer; + ktime_t next_event_c = per_cpu(next_hrtimer, next_cpu); if (next_event > next_event_c) next_event = next_event_c; @@ -775,7 +776,7 @@ static unsigned int get_next_online_cpu(bool from_idle) return next_cpu; next_event = KTIME_MAX; for_each_online_cpu(cpu) { - ktime_t next_event_c = per_cpu(cpu_lpm, cpu)->next_hrtimer; + ktime_t next_event_c = per_cpu(next_hrtimer, cpu); if (next_event_c < next_event) { next_event = next_event_c; @@ -802,7 +803,7 @@ static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster, &cluster->num_children_in_sync, cpu_online_mask); for_each_cpu(cpu, &online_cpus_in_cluster) { - ktime_t next_event_c = per_cpu(cpu_lpm, cpu)->next_hrtimer; + ktime_t next_event_c = per_cpu(next_hrtimer, cpu); if (next_event_c < next_event) next_event = next_event_c; @@ -1448,7 +1449,7 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev, int ret = -EBUSY; /* Read the timer from the CPU that is entering idle */ - cpu->next_hrtimer = tick_nohz_get_next_hrtimer(); + per_cpu(next_hrtimer, dev->cpu) = tick_nohz_get_next_hrtimer(); cpu_prepare(cpu, idx, true); cluster_prepare(cpu->parent, cpumask, idx, true, start_time); diff --git a/drivers/cpuidle/lpm-levels.h b/drivers/cpuidle/lpm-levels.h index 5b4fa93f1632..153603390484 100644 --- a/drivers/cpuidle/lpm-levels.h +++ b/drivers/cpuidle/lpm-levels.h @@ -69,7 +69,6 @@ struct lpm_cpu { uint64_t bias; struct cpuidle_driver *drv; struct lpm_cluster *parent; - ktime_t next_hrtimer; }; struct lpm_level_avail {