OSDN Git Service

ANDROID: 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)
committerChris Redpath <chris.redpath@arm.com>
Tue, 19 Dec 2017 13:25:40 +0000 (13:25 +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>
Change-Id: Ib3d1178512735b0e314881f73fb8ccff5a69319f
Signed-off-by: Chris Redpath <chris.redpath@arm.com>
drivers/cpuidle/cpuidle.c
include/linux/cpuidle.h
kernel/sched/idle.c
kernel/sched/sched.h

index 484cc89..21a1833 100644 (file)
@@ -211,7 +211,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());
@@ -225,7 +225,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 8f7788d..b7c12ee 100644 (file)
@@ -214,7 +214,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
index 257f4f0..c1dbb2c 100644 (file)
@@ -25,9 +25,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;
index 8328e6b..6e56411 100644 (file)
@@ -799,6 +799,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
 };
 
@@ -1513,6 +1514,17 @@ static inline struct cpuidle_state *idle_get_state(struct rq *rq)
        SCHED_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)
@@ -1523,6 +1535,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 schedule_idle(void);