From a239bb4b6299401a4c2f5b300ec3a2971e149019 Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Mon, 1 Jun 2020 12:13:55 -0700 Subject: [PATCH] cpuidle: Mark CPUs idle as late as possible to avoid unneeded IPIs It isn't guaranteed a CPU will idle upon calling lpm_cpuidle_enter(), since it could abort early at the need_resched() check. In this case, it's possible for an IPI to be sent to this "idle" CPU needlessly, thus wasting power. For the same reason, it's also wasteful to keep a CPU marked idle even after it's woken up. Reduce the window that CPUs are marked idle to as small as it can be in order to improve power consumption. Signed-off-by: Sultan Alsawaf --- drivers/cpuidle/cpuidle.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 3f115217c3ef..f823dd3f9480 100755 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -44,18 +44,15 @@ static atomic_t idled = ATOMIC_INIT(0); #error idled CPU mask not big enough for NR_CPUS #endif -static void cpuidle_set_idle_cpu(unsigned int cpu) +void cpuidle_set_idle_cpu(unsigned int cpu) { atomic_or(BIT(cpu), &idled); } -static void cpuidle_clear_idle_cpu(unsigned int cpu) +void cpuidle_clear_idle_cpu(unsigned int cpu) { atomic_andnot(BIT(cpu), &idled); } -#else -static inline void cpuidle_set_idle_cpu(unsigned int cpu) { } -static inline void cpuidle_clear_idle_cpu(unsigned int cpu) { } #endif int cpuidle_disabled(void) @@ -240,9 +237,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, time_start = ns_to_ktime(local_clock()); stop_critical_timings(); - cpuidle_set_idle_cpu(dev->cpu); entered_state = target_state->enter(dev, drv, index); - cpuidle_clear_idle_cpu(dev->cpu); start_critical_timings(); sched_clock_idle_wakeup_event();