From 8bd86be3cc737a7318f28dc915d28344f01ae061 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Tue, 28 Apr 2020 14:02:19 -0600 Subject: [PATCH] cpuidle: record state entry failed statistics When CPUs fail to enter the chosen idle state because of pending interrupt, let's record that and show along with other statistics for the idle state. Change-Id: I22265e8a86160c98a7ae810808b6b4821a6633b6 Signed-off-by: Lina Iyer --- drivers/cpuidle/Kconfig | 11 +++++++++++ drivers/cpuidle/cpuidle.c | 3 +++ drivers/cpuidle/sysfs.c | 9 +++++++++ include/linux/cpuidle.h | 3 +++ 4 files changed, 26 insertions(+) diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index 88727b7c0d59..3e1bfa23e363 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig @@ -18,6 +18,17 @@ if CPU_IDLE config CPU_IDLE_MULTIPLE_DRIVERS bool +config QGKI_CPUIDLE_FAILED_STAT + bool "Record failed attempts at entering idle states" + depends on QGKI + help + CPU idle maintains statistics for successful entry to each idle + state. It is also useful to record statistics of failure to + enter each idle state. + + Save and report the failed statistics in sysfs along with usage + statistics. + config CPU_IDLE_GOV_LADDER bool "Ladder governor (for periodic timer tick)" diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 8b113c30d507..7a7aeb2d23e5 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -291,6 +291,9 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, } } else { dev->last_residency = 0; +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT + dev->states_usage[index].failed++; +#endif } return entered_state; diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index f8747322b3c7..12c1152fb1a0 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -297,6 +297,9 @@ define_show_state_function(target_residency) define_show_state_function(power_usage) define_show_state_ull_function(usage) define_show_state_ull_function(time) +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT +define_show_state_ull_function(failed) +#endif define_show_state_str_function(name) define_show_state_str_function(desc) define_show_state_ull_function(disable) @@ -310,6 +313,9 @@ define_one_state_ro(latency, show_state_exit_latency); define_one_state_ro(residency, show_state_target_residency); define_one_state_ro(power, show_state_power_usage); define_one_state_ro(usage, show_state_usage); +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT +define_one_state_ro(failed, show_state_failed); +#endif define_one_state_ro(time, show_state_time); define_one_state_rw(disable, show_state_disable, store_state_disable); define_one_state_ro(above, show_state_above); @@ -322,6 +328,9 @@ static struct attribute *cpuidle_state_default_attrs[] = { &attr_residency.attr, &attr_power.attr, &attr_usage.attr, +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT + &attr_failed.attr, +#endif &attr_time.attr, &attr_disable.attr, &attr_above.attr, diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 372fa432bcad..f41780933063 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -35,6 +35,9 @@ struct cpuidle_state_usage { unsigned long long time; /* in US */ unsigned long long above; /* Number of times it's been too deep */ unsigned long long below; /* Number of times it's been too shallow */ +#ifdef CONFIG_QGKI_CPUIDLE_FAILED_STAT + unsigned long long failed; /* Number of times it failed to enter */ +#endif #ifdef CONFIG_SUSPEND unsigned long long s2idle_usage; unsigned long long s2idle_time; /* in US */