Skip to content

Commit f49735f

Browse files
Lina Iyerrafaeljw
authored andcommitted
cpuidle: record state entry rejection statistics
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>
1 parent 70c179b commit f49735f

4 files changed

Lines changed: 14 additions & 0 deletions

File tree

Documentation/admin-guide/pm/cpuidle.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,10 @@ object corresponding to it, as follows:
528528
Total number of times the hardware has been asked by the given CPU to
529529
enter this idle state.
530530

531+
``rejected``
532+
Total number of times a request to enter this idle state on the given
533+
CPU was rejected.
534+
531535
The :file:`desc` and :file:`name` files both contain strings. The difference
532536
between them is that the name is expected to be more concise, while the
533537
description may be longer and it may contain white space or special characters.
@@ -572,6 +576,11 @@ particular case. For these reasons, the only reliable way to find out how
572576
much time has been spent by the hardware in different idle states supported by
573577
it is to use idle state residency counters in the hardware, if available.
574578

579+
Generally, an interrupt received when trying to enter an idle state causes the
580+
idle state entry request to be rejected, in which case the ``CPUIdle`` driver
581+
may return an error code to indicate that this was the case. The :file:`usage`
582+
and :file:`rejected` files report the number of times the given idle state
583+
was entered successfully or rejected, respectively.
575584

576585
.. _cpu-pm-qos:
577586

drivers/cpuidle/cpuidle.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
307307
}
308308
} else {
309309
dev->last_residency_ns = 0;
310+
dev->states_usage[index].rejected++;
310311
}
311312

312313
return entered_state;

drivers/cpuidle/sysfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ define_show_state_time_function(exit_latency)
256256
define_show_state_time_function(target_residency)
257257
define_show_state_function(power_usage)
258258
define_show_state_ull_function(usage)
259+
define_show_state_ull_function(rejected)
259260
define_show_state_str_function(name)
260261
define_show_state_str_function(desc)
261262
define_show_state_ull_function(above)
@@ -312,6 +313,7 @@ define_one_state_ro(latency, show_state_exit_latency);
312313
define_one_state_ro(residency, show_state_target_residency);
313314
define_one_state_ro(power, show_state_power_usage);
314315
define_one_state_ro(usage, show_state_usage);
316+
define_one_state_ro(rejected, show_state_rejected);
315317
define_one_state_ro(time, show_state_time);
316318
define_one_state_rw(disable, show_state_disable, store_state_disable);
317319
define_one_state_ro(above, show_state_above);
@@ -325,6 +327,7 @@ static struct attribute *cpuidle_state_default_attrs[] = {
325327
&attr_residency.attr,
326328
&attr_power.attr,
327329
&attr_usage.attr,
330+
&attr_rejected.attr,
328331
&attr_time.attr,
329332
&attr_disable.attr,
330333
&attr_above.attr,

include/linux/cpuidle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct cpuidle_state_usage {
3838
u64 time_ns;
3939
unsigned long long above; /* Number of times it's been too deep */
4040
unsigned long long below; /* Number of times it's been too shallow */
41+
unsigned long long rejected; /* Number of times idle entry was rejected */
4142
#ifdef CONFIG_SUSPEND
4243
unsigned long long s2idle_usage;
4344
unsigned long long s2idle_time; /* in US */

0 commit comments

Comments
 (0)