From: Aubrey Li <aubrey...@linux.intel.com> Reflect the data to cpuidle governor when there is an update --- drivers/cpuidle/cpuidle.c | 6 ++++-- include/linux/cpuidle.h | 1 + kernel/sched/idle.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 97aacab..9c84c5c 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -387,9 +387,11 @@ unsigned int cpuidle_predict(void) /* * Give the governor an opportunity to update on the outcome */ - cpuidle_update(drv, dev); - gov_stat = (struct cpuidle_governor_stat *)&(dev->gov_stat); + if (gov_stat->needs_update) { + cpuidle_update(drv, dev); + gov_stat->needs_update = 0; + } gov_stat->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length()); get_iowait_load(&nr_iowaiters, &cpu_load); diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index b9964ec..c6a805f 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -79,6 +79,7 @@ struct cpuidle_state { struct cpuidle_governor_stat { int last_state_idx; + int needs_update; unsigned int next_timer_us; unsigned int predicted_us; diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 16a766c..3358db2 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -187,6 +187,7 @@ static void cpuidle_idle_call(void) * Give the governor an opportunity to reflect on the outcome */ cpuidle_reflect(dev, entered_state); + dev->gov_stat.needs_update = 1; } exit_idle: @@ -206,6 +207,10 @@ static void cpuidle_idle_call(void) */ static void cpuidle_fast(void) { + struct cpuidle_device *dev = cpuidle_get_device(); + ktime_t time_start, time_end; + s64 diff; + while (!need_resched()) { check_pgt_cache(); rmb(); @@ -218,7 +223,16 @@ static void cpuidle_fast(void) local_irq_disable(); arch_cpu_idle_enter(); + time_start = ns_to_ktime(local_clock()); default_idle_call(); + time_end = ns_to_ktime(local_clock()); + + diff = ktime_us_delta(time_end, time_start); + if (diff > INT_MAX) + diff = INT_MAX; + + dev->last_residency = (int) diff; + dev->gov_stat.needs_update = 1; arch_cpu_idle_exit(); } -- 2.7.4