CPU frequency and idle states

This data source is available on Linux and Android (Since P). It records changes in the CPU power management scheme through the Linux kernel ftrace infrastructure. It involves three aspects:

Frequency scaling

Records changes in the frequency of a CPU. An event is emitted every time the scaling governor scales the CPU frequency up or down.

On most Android devices the frequency scaling is per-cluster (group of big/little cores) so it's not unusual to see groups of four CPUs changing frequency at the same time.

idle states

When no threads are eligible to be executed (e.g. they are all in sleep states) the kernel sets the CPU into an idle state, turning off some of the circuitry to reduce idle power usage. Most modern CPUs have more than one idle state: deeper idle states use less power but also require more time to resume from.

Note that idle transitions are relatively fast and cheap, a CPU can enter and leave idle states hundreds of times in a second. Idle-ness must not be confused with full device suspend, which is a stronger and more invasive power saving state (See below). CPUs can be idle even when the screen is on and the device looks operational.

The details about how many idle states are available and their semantic is highly CPU/SoC specific. At the trace level, the idle state 0 means not-idle, values greater than 0 represent increasingly deeper power saving states (e.g., single core idle -> full package idle).

Note that most Android devices won't enter idle states as long as the USB cable is plugged in (the USB driver stack holds wakelocks). It is not unusual to see only one idle state in traces collected through USB.

On most SoCs the frequency has little value when the CPU is idle, as the CPU is typically clock-gated in idle states. In those cases the frequency in the trace happens to be the last frequency the CPU was running at before becoming idle.

Known issues:

UI

In the UI, CPU frequency and idle-ness are shown on the same track. The height of the track represents the frequency, the coloring represents the idle state (colored: not-idle, gray: idle). Hovering or clicking a point in the track will reveal both the frequency and the idle state:

SQL

At the SQL level, both frequency and idle states are modeled as counters, Note that the cpuidle value 0xffffffff (4294967295) means back to not-idle.

select ts, t.name, cpu, value from counter as c left join cpu_counter_track as t on c.track_id = t.id where t.name = 'cpuidle' or t.name = 'cpufreq'
ts name cpu value
261187013242350 cpuidle 1 0
261187013246204 cpuidle 1 4294967295
261187013317818 cpuidle 1 0
261187013333027 cpuidle 0 0
261187013338287 cpufreq 0 1036800
261187013357922 cpufreq 1 1036800
261187013410735 cpuidle 1 4294967295
261187013451152 cpuidle 0 4294967295
261187013665683 cpuidle 1 0
261187013845058 cpufreq 0 1900800

TraceConfig

data_sources: { config { name: "linux.ftrace" ftrace_config { ftrace_events: "power/cpu_frequency" ftrace_events: "power/cpu_idle" ftrace_events: "power/suspend_resume" } } }

Full-device suspend

Full device suspend happens when a laptop is put in "sleep" mode (e.g. by closing the lid) or when a smartphone display is turned off for enough time.

When the device is suspended, most of the hardware units are turned off entering the highest power-saving state possible (other than full shutdown).

Note that most Android devices don't suspend immediately after dimming the display but tend to do so if the display is forced off through the power button. The details are highly device/manufacturer/kernel specific.

Known issues: