From f0b280c3957aa9e306fe60309105b16cab114856 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Wed, 30 Jun 2021 16:40:22 +0530 Subject: [PATCH] ANDROID: cpuidle: Update cpuidle_uninstall_idle_handler() to wakeup all online CPUs wake_up_all_idle_cpus() will not wakeup paused CPUs since they are removed from cpu_active_mask but paused CPUs can be in deep cpu idle and hence must wakeup when uninstalling idle handler. This change fixes this by introducing wake_up_all_online_idle_cpus() to unconditionally wakeup all online idle CPUs and invoking same when uninstalling cpu idle handler. Bug: 192436062 Fixes: 683010f555d8 ("ANDROID: cpu/hotplug: add pause/resume_cpus interface") Change-Id: I4afd4b7a17b87f9cc495e7009c9537888387f9ef Signed-off-by: Maulik Shah --- drivers/cpuidle/cpuidle.c | 2 +- include/linux/smp.h | 2 ++ kernel/smp.c | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 3bf28f4ebe74..500f265e0d14 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -428,7 +428,7 @@ void cpuidle_uninstall_idle_handler(void) { if (enabled_devices) { initialized = 0; - wake_up_all_idle_cpus(); + wake_up_all_online_idle_cpus(); } /* diff --git a/include/linux/smp.h b/include/linux/smp.h index 04f44e0aa2e0..7ce15c3be7aa 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -127,6 +127,7 @@ int smp_call_function_any(const struct cpumask *mask, void kick_all_cpus_sync(void); void wake_up_all_idle_cpus(void); +void wake_up_all_online_idle_cpus(void); /* * Generic and arch helpers @@ -182,6 +183,7 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func, static inline void kick_all_cpus_sync(void) { } static inline void wake_up_all_idle_cpus(void) { } +static inline void wake_up_all_online_idle_cpus(void) { } #ifdef CONFIG_UP_LATE_INIT extern void __init up_late_init(void); diff --git a/kernel/smp.c b/kernel/smp.c index b5dd54708781..6677e077e4be 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -967,6 +967,27 @@ void wake_up_all_idle_cpus(void) } EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus); +/** + * wake_up_all_online_idle_cpus - break all online cpus out of idle + * wake_up_all_online_idle_cpus try to break all online cpus which is in idle + * state even including idle polling cpus, for non-idle cpus, we will do nothing + * for them. + */ +void wake_up_all_online_idle_cpus(void) +{ + int cpu; + + preempt_disable(); + for_each_online_cpu(cpu) { + if (cpu == smp_processor_id()) + continue; + + wake_up_if_idle(cpu); + } + preempt_enable(); +} +EXPORT_SYMBOL_GPL(wake_up_all_online_idle_cpus); + /** * smp_call_on_cpu - Call a function on a specific cpu *