diff options
author | morten.rasmussen@arm.com <morten.rasmussen@arm.com> | 2015-07-07 19:24:10 +0100 |
---|---|---|
committer | Vincent Guittot <vincent.guittot@linaro.org> | 2015-07-27 17:59:40 +0200 |
commit | 14bc6b45c1f914c553eaa6bb5c7250ebcb5acaa6 (patch) | |
tree | df326abcb5fff54b2b09e96b4fda632f1752b802 | |
parent | 6319325e52844261f3030cd57c4e9793946a21da (diff) |
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 <mingo@redhat.com>
cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Morten Rasmussen <morten.rasmussen@arm.com>
-rw-r--r-- | kernel/sched/idle.c | 8 | ||||
-rw-r--r-- | kernel/sched/sched.h | 21 |
2 files changed, 29 insertions, 0 deletions
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 594275ed2620..f49f27cb554c 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -108,12 +108,20 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev, return -EBUSY; } + /* Take note of the planned idle state. */ + idle_set_state(this_rq(), &drv->states[next_state]); + idle_set_state_idx(this_rq(), next_state); + /* * Enter the idle state previously returned by the governor decision. * This function will block until an interrupt occurs and will take * care of re-enabling the local interrupts */ return cpuidle_enter(drv, dev, next_state); + + idle_set_state(this_rq(), NULL); + idle_set_state_idx(this_rq(), -1); + } /** diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index fcbe1a4a8dba..6a78f5c7aaba 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -703,6 +703,7 @@ struct rq { #ifdef CONFIG_CPU_IDLE /* Must be inspected within a rcu lock section */ struct cpuidle_state *idle_state; + int idle_state_idx; #endif }; @@ -1332,6 +1333,17 @@ static inline struct cpuidle_state *idle_get_state(struct rq *rq) WARN_ON(!rcu_read_lock_held()); return rq->idle_state; } + +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(struct rq *rq, struct cpuidle_state *idle_state) @@ -1342,6 +1354,15 @@ static inline struct cpuidle_state *idle_get_state(struct rq *rq) { return NULL; } + +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 sysrq_sched_debug_show(void); |