Skip to content

Commit

Permalink
cpuidle: record state entry rejection statistics
Browse files Browse the repository at this point in the history
CPUs may fail to enter the chosen idle state if there was a
pending interrupt, causing the cpuidle driver to return an error
value.

Record that and export it via sysfs along with the other idle state
statistics.

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@codeaurora.org>
[ rjw: Changelog and documentation edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Lina Iyer authored and rafaeljw committed Sep 23, 2020
1 parent 70c179b commit f49735f
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Documentation/admin-guide/pm/cpuidle.rst
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,10 @@ 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 a request to enter this idle state on the given
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.
Expand Down Expand Up @@ -572,6 +576,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 trying to enter an idle state causes the
idle state entry request to be rejected, in which case the ``CPUIdle`` driver
may return an error code to indicate that this was the case. The :file:`usage`
and :file:`rejected` files report the number of times the given idle state
was entered successfully or rejected, respectively.

.. _cpu-pm-qos:

Expand Down
1 change: 1 addition & 0 deletions drivers/cpuidle/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions drivers/cpuidle/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand Down
1 change: 1 addition & 0 deletions include/linux/cpuidle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit f49735f

Please sign in to comment.