From 478df4d9052480d43f6aeb393174180fb6711276 Mon Sep 17 00:00:00 2001 From: Morten Rasmussen Date: Tue, 27 Jan 2015 13:48:07 +0000 Subject: [PATCH] ANDROID: sched, cpuidle: Track cpuidle state index in the scheduler The idle-state of each cpu is currently pointed to by rq->idle_state but there isn't any information in the struct cpuidle_state that can used to look up the idle-state energy model data stored in struct sched_group_energy. For this purpose is necessary to store the idle state index as well. Ideally, the idle-state data should be unified. cc: Ingo Molnar cc: Peter Zijlstra Signed-off-by: Morten Rasmussen Change-Id: Ib3d1178512735b0e314881f73fb8ccff5a69319f Signed-off-by: Chris Redpath (cherry picked from commit a732c97420e109956c20f34c70b91e6d06f5df31) [ Fixed trivial cherry-pick conflict in kernel/sched/sched.h ] Signed-off-by: Quentin Perret [satyap@codeaurora.org: port to msm-5.x from msm-4.19 and add WALT check around idle_state_idx usage] Signed-off-by: Satya Durga Srinivasu Prabhala --- drivers/cpuidle/cpuidle.c | 4 ++-- include/linux/cpuidle.h | 2 +- kernel/sched/idle.c | 3 ++- kernel/sched/sched.h | 27 +++++++++++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 0895b988fa92..54c90b571148 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -220,7 +220,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, } /* Take note of the planned idle state. */ - sched_idle_set_state(target_state); + sched_idle_set_state(target_state, index); trace_cpu_idle_rcuidle(index, dev->cpu); time_start = ns_to_ktime(local_clock()); @@ -234,7 +234,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); /* The cpu is no longer idle or about to enter idle. */ - sched_idle_set_state(NULL); + sched_idle_set_state(NULL, -1); if (broadcast) { if (WARN_ON_ONCE(!irqs_disabled())) diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 4b6b5bea8f79..954cd9b3a4ec 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -221,7 +221,7 @@ static inline void cpuidle_use_deepest_state(bool enable) #endif /* kernel/sched/idle.c */ -extern void sched_idle_set_state(struct cpuidle_state *idle_state); +extern void sched_idle_set_state(struct cpuidle_state *idle_state, int index); extern void default_idle_call(void); #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index f65ef1e2f204..ee68dea4b11a 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -17,9 +17,10 @@ extern char __cpuidle_text_start[], __cpuidle_text_end[]; * sched_idle_set_state - Record idle state for the current CPU. * @idle_state: State to record. */ -void sched_idle_set_state(struct cpuidle_state *idle_state) +void sched_idle_set_state(struct cpuidle_state *idle_state, int index) { idle_set_state(this_rq(), idle_state); + idle_set_state_idx(this_rq(), index); } static int __read_mostly cpu_idle_force_poll; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index be33a384c9e0..e83bdf6bce23 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1008,6 +1008,9 @@ struct rq { #ifdef CONFIG_CPU_IDLE /* Must be inspected within a rcu lock section */ struct cpuidle_state *idle_state; +#ifdef CONFIG_SCHED_WALT + int idle_state_idx; +#endif #endif }; @@ -1854,6 +1857,7 @@ static inline struct cpuidle_state *idle_get_state(struct rq *rq) return rq->idle_state; } + #else static inline void idle_set_state(struct rq *rq, struct cpuidle_state *idle_state) @@ -1866,6 +1870,29 @@ static inline struct cpuidle_state *idle_get_state(struct rq *rq) } #endif +#if defined(CONFIG_CPU_IDLE) && defined (CONFIG_SCHED_WALT) +static inline void idle_set_state_idx(struct rq *rq, int idle_state_idx) +{ + rq->idle_state_idx = idle_state_idx; +} + +static inline int idle_get_state_idx(struct rq *rq) +{ + WARN_ON(!rcu_read_lock_held()); + return rq->idle_state_idx; +} + +#else +static inline void idle_set_state_idx(struct rq *rq, int idle_state_idx) +{ +} + +static inline int idle_get_state_idx(struct rq *rq) +{ + return -1; +} +#endif + extern void schedule_idle(void); extern void sysrq_sched_debug_show(void);