On Tue, Sep 22, 2020 at 8:34 PM Lina Iyer <ilina@xxxxxxxxxxxxxx> wrote: > > CPUs may fail to enter the chosen idle state if there was a pending > interrupt. The cpuidle driver would return an error value in that case. > Let's record that and show along with other statistics for the idle > state. This could prove useful in understanding behavior of the governor > and the system during usecases that involve multiple CPUs. > > Signed-off-by: Lina Iyer <ilina@xxxxxxxxxxxxxx> Applied as 5.10 material with some changelog and documentation edits, thanks! > > --- > Changes in v2: > - Rename 'failed' to 'rejected' > - Update documentation > --- > Documentation/admin-guide/pm/cpuidle.rst | 8 ++++++++ > drivers/cpuidle/cpuidle.c | 1 + > drivers/cpuidle/sysfs.c | 3 +++ > include/linux/cpuidle.h | 1 + > 4 files changed, 13 insertions(+) > > diff --git a/Documentation/admin-guide/pm/cpuidle.rst b/Documentation/admin-guide/pm/cpuidle.rst > index a96a423e3779..1e7fd7a64c65 100644 > --- a/Documentation/admin-guide/pm/cpuidle.rst > +++ b/Documentation/admin-guide/pm/cpuidle.rst > @@ -528,6 +528,9 @@ object corresponding to it, as follows: > Total number of times the hardware has been asked by the given CPU to > enter this idle state. > > +``rejected`` > + Total number of times the idle state requested to the CPU was rejected. > + > The :file:`desc` and :file:`name` files both contain strings. The difference > between them is that the name is expected to be more concise, while the > description may be longer and it may contain white space or special characters. > @@ -572,6 +575,11 @@ particular case. For these reasons, the only reliable way to find out how > much time has been spent by the hardware in different idle states supported by > it is to use idle state residency counters in the hardware, if available. > > +Generally, an interrupt received when entering idle state would cause the idle > +state entry request to be rejected. The return value from the cpuidle driver > +indicates whether the idle state was entered or rejected. The files > +:file:`usage` and :file:`rejected` report the number of times the idle states > +were successfully entered and rejected, respectively. > > .. _cpu-pm-qos: > > diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c > index 6c7e5621cf9a..0ed5030b89d6 100644 > --- a/drivers/cpuidle/cpuidle.c > +++ b/drivers/cpuidle/cpuidle.c > @@ -307,6 +307,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, > } > } else { > dev->last_residency_ns = 0; > + dev->states_usage[index].rejected++; > } > > return entered_state; > diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c > index 091d1caceb41..53ec9585ccd4 100644 > --- a/drivers/cpuidle/sysfs.c > +++ b/drivers/cpuidle/sysfs.c > @@ -256,6 +256,7 @@ define_show_state_time_function(exit_latency) > define_show_state_time_function(target_residency) > define_show_state_function(power_usage) > define_show_state_ull_function(usage) > +define_show_state_ull_function(rejected) > define_show_state_str_function(name) > define_show_state_str_function(desc) > define_show_state_ull_function(above) > @@ -312,6 +313,7 @@ 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); > +define_one_state_ro(rejected, show_state_rejected); > 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); > @@ -325,6 +327,7 @@ static struct attribute *cpuidle_state_default_attrs[] = { > &attr_residency.attr, > &attr_power.attr, > &attr_usage.attr, > + &attr_rejected.attr, > &attr_time.attr, > &attr_disable.attr, > &attr_above.attr, > diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h > index 6175c77bf25e..ed0da0e58e8b 100644 > --- a/include/linux/cpuidle.h > +++ b/include/linux/cpuidle.h > @@ -38,6 +38,7 @@ struct cpuidle_state_usage { > u64 time_ns; > unsigned long long above; /* Number of times it's been too deep */ > unsigned long long below; /* Number of times it's been too shallow */ > + unsigned long long rejected; /* Number of times idle entry was rejected */ > #ifdef CONFIG_SUSPEND > unsigned long long s2idle_usage; > unsigned long long s2idle_time; /* in US */ > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project >