If the next idle is expected to be a fast idle, we should keep tick on before going into idle
Signed-off-by: Aubrey Li <aubrey...@linux.intel.com> --- drivers/cpuidle/cpuidle.c | 14 ++++++++++++++ include/linux/cpuidle.h | 2 ++ kernel/time/tick-sched.c | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index ef6f7dd..6cb7e17 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -370,6 +370,20 @@ void cpuidle_predict(void) } /** + * cpuidle_fast_idle - predict whether or not the coming idle is a fast idle + * This function can be called in irq exit path, make it as soon as possible + */ +bool cpuidle_fast_idle(void) +{ + struct cpuidle_device *dev = cpuidle_get_device(); + + if (!dev) + return false; + + return dev->idle_stat.fast_idle; +} + +/** * cpuidle_install_idle_handler - installs the cpuidle idle loop handler */ void cpuidle_install_idle_handler(void) diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 9ca0288..791db15 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -144,6 +144,7 @@ extern int cpuidle_select(struct cpuidle_driver *drv, extern void cpuidle_entry_start(void); extern void cpuidle_entry_end(void); extern void cpuidle_predict(void); +extern bool cpuidle_fast_idle(void); extern int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev, int index); extern void cpuidle_reflect(struct cpuidle_device *dev, int index); @@ -180,6 +181,7 @@ static inline int cpuidle_select(struct cpuidle_driver *drv, static inline void cpuidle_entry_start(void) { } static inline void cpuidle_entry_end(void) { } static inline void cpuidle_predict(void) { } +static inline void cpuidle_fast_idle(void) {return false; } static inline int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev, int index) {return -ENODEV; } diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index c7a899c..d663fab 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -27,6 +27,7 @@ #include <linux/irq_work.h> #include <linux/posix-timers.h> #include <linux/context_tracking.h> +#include <linux/cpuidle.h> #include <asm/irq_regs.h> @@ -916,6 +917,9 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) return false; } + if (cpuidle_fast_idle()) + return false; + return true; } -- 2.7.4