sched, cpuidle: Track cpuidle state index in the scheduler
authorMorten Rasmussen <morten.rasmussen@arm.com>
Tue, 27 Jan 2015 13:48:07 +0000 (13:48 +0000)
committerPunit Agrawal <punit.agrawal@arm.com>
Mon, 21 Mar 2016 12:34:30 +0000 (12:34 +0000)
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>
drivers/cpuidle/cpuidle.c
include/linux/cpuidle.h
kernel/sched/idle.c
kernel/sched/sched.h

index 17a6dc0e211110f00ac2e73728414f161d5a194f..b9a6cceb7bac071b76aab5da647c8a4b7321b4b4 100644 (file)
@@ -192,7 +192,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 = ktime_get();
@@ -205,7 +205,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()))
index 786ad32631a672695d88b47d67c1019df624acab..6eae1576499e06b421592236e6e2f3c9c550efb9 100644 (file)
@@ -204,7 +204,7 @@ static inline int cpuidle_enter_freeze(struct cpuidle_driver *drv,
 #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
index 4a2ef5a02fd3f91d7c4228378c23d5606bb73812..cbc130efbc5bc6a63ced39f4f1325e7d81c0ec79 100644 (file)
  * 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;
index 5323d4fc1109c0428760e39f407360cfd4a4ef3e..2301b0476b90918b82f4c6686d3f07711ff48ff3 100644 (file)
@@ -693,6 +693,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
 };
 
@@ -1285,6 +1286,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)
@@ -1295,6 +1307,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);