Enabling CPU frequency and voltage scaling statistics in the Linux kernel

I’m having trouble getting the /sys/devices/system/cpu/cpu0/cpufreq/stats/ directory to appear on my relatively vanilla Fedora 36 workstation system. I must be missing something because as far as I can tell this kernel feature is enabled on Fedora. Does anybody have ideas about this?

General Description of sysfs CPUFreq Stats — The Linux Kernel documentation states that enabling CONFIG_CPU_FREQ_STAT in the kernel’s build time config will enable a per-CPU stats directory /sys/devices/system/cpu/cpu*/cpufreq/stats/. It will contain various files revealing frequency statistics for each CPU.

This option is (apparently) enabled on Fedora but I don’t see the stats directory.

% grep CONFIG_CPU_FREQ_STAT /boot/config-*
/boot/config-5.18.16-200.fc36.x86_64:CONFIG_CPU_FREQ_STAT=y
/boot/config-5.18.17-200.fc36.x86_64:CONFIG_CPU_FREQ_STAT=y
/boot/config-5.18.18-200.fc36.x86_64:CONFIG_CPU_FREQ_STAT=y
% ls -d /sys/devices/system/cpu/cpu*/cpufreq/stats
zsh: no matches found: /sys/devices/system/cpu/cpu*/cpufreq/stats
% cd /sys/devices/system/cpu/cpu0/cpufreq
% ls -l
-r--r--r--. 1 root root 4096 Aug 24 07:20 affected_cpus
-r--r--r--. 1 root root 4096 Aug 22 07:52 cpuinfo_max_freq
-r--r--r--. 1 root root 4096 Aug 24 07:20 cpuinfo_min_freq
-r--r--r--. 1 root root 4096 Aug 24 07:20 cpuinfo_transition_latency
-r--r--r--. 1 root root 4096 Aug 24 07:20 related_cpus
-r--r--r--. 1 root root 4096 Aug 24 07:20 scaling_available_governors
-r--r--r--. 1 root root 4096 Aug 24 07:20 scaling_cur_freq
-r--r--r--. 1 root root 4096 Aug 24 07:20 scaling_driver
-rw-r--r--. 1 root root 4096 Aug 24 07:20 scaling_governor
-rw-r--r--. 1 root root 4096 Aug 24 07:20 scaling_max_freq
-rw-r--r--. 1 root root 4096 Aug 24 07:20 scaling_min_freq
-rw-r--r--. 1 root root 4096 Aug 24 07:28 scaling_setspeed

1 Like

I assume you mean /sys and not /sysfs? I’m able to get the current frequency for mine with /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq (replace cpu0 with 0-15) and this command works for me:

$  ls /sys/devices/system/cpu/cpu*/cpufreq/stats
/sys/devices/system/cpu/cpu0/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu10/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu11/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu12/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu13/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu14/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu15/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu1/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu2/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu3/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu4/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu5/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu6/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu7/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu8/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

/sys/devices/system/cpu/cpu9/cpufreq/stats:
reset  time_in_state  total_trans  trans_table

I’m running the stock Fedora 36 kerneL (5.18.17-200.fc36.x86_64) with a Ryzen 7 PRO and this is a regular user bash shell.

Can you give us the output of inxi -C and uname -r ?

Thanks for taking a look Scott.

Yes, /sys is where the “sysfs” filesystem is usually mounted. The kernel doc I linked to use the (arguably confusing) /sysfs/devices/system/cpu/ paths which I repeated here. I’ve corrected my first post.

It occurred to me that perhaps my CPU is too old for this feature (a circa 2014-15 laptop if I recall). I seem to be using the intel_cpufreq driver and schedutil governer, which strike me as normal.

Poking around in the kernel sources in a superficial way suggested to me that exporting these stats is conditional on some things, but I don’t understand what.

Output of the commands you asked for.

% inxi -C
CPU:
  Info: dual core model: Intel Core i5-5200U bits: 64 type: MT MCP cache:
    L2: 512 KiB
  Speed (MHz): avg: 2540 min/max: 500/2700 cores: 1: 2495 2: 2532 3: 2494
    4: 2639
% uname -r
5.18.18-200.fc36.x86_64
% cpupower frequency-info
analyzing CPU 0:
  driver: intel_cpufreq
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 20.0 us
  hardware limits: 500 MHz - 2.70 GHz
  available cpufreq governors: conservative ondemand userspace powersave performance schedutil
  current policy: frequency should be within 500 MHz and 2.70 GHz.
                  The governor "schedutil" may decide which speed to use
                  within this range.
  current CPU frequency: Unable to call hardware
  current CPU frequency: 1.96 GHz (asserted by call to kernel)
  boost state support:
    Supported: yes
    Active: yes
1 Like

On my system I find the stats at /sys/devices/system/cpu/cpufreq/policy0/stats

# cpupower frequency-info
analyzing CPU 0:
  driver: acpi-cpufreq
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency:  Cannot determine or is not supported.
  hardware limits: 2.20 GHz - 4.21 GHz
  available frequency steps:  3.60 GHz, 2.80 GHz, 2.20 GHz
  available cpufreq governors: conservative ondemand userspace powersave performance schedutil
  current policy: frequency should be within 2.20 GHz and 3.60 GHz.
                  The governor "schedutil" may decide which speed to use
                  within this range.
  current CPU frequency: 2.20 GHz (asserted by call to hardware)
  boost state support:
    Supported: yes
    Active: yes
    Boost States: 0
    Total States: 3
    Pstate-P0:  3600MHz
    Pstate-P1:  2800MHz
    Pstate-P2:  2200MHz

Yes, the “cpufreq” directory is symlinked from the cpu/cpuN directories. I think you’ll find the cpufreq/stats directory in both places, whereas I have the cpufreq directory without a stats subdirectory.

% ls -l /sys/devices/system/cpu/cpu*/cpufreq
lrwxrwxrwx. 1 root root 0 Aug 22 07:51 /sys/devices/system/cpu/cpu0/cpufreq -> ../cpufreq/policy0/
lrwxrwxrwx. 1 root root 0 Aug 25 07:08 /sys/devices/system/cpu/cpu1/cpufreq -> ../cpufreq/policy1/
lrwxrwxrwx. 1 root root 0 Aug 25 07:08 /sys/devices/system/cpu/cpu2/cpufreq -> ../cpufreq/policy2/
lrwxrwxrwx. 1 root root 0 Aug 25 07:08 /sys/devices/system/cpu/cpu3/cpufreq -> ../cpufreq/policy3/
% ls -l /sys/devices/system/cpu/cpufreq/policy0
total 0
-r--r--r--. 1 root root 4096 Aug 25 07:10 affected_cpus
-r--r--r--. 1 root root 4096 Aug 22 07:52 cpuinfo_max_freq
-r--r--r--. 1 root root 4096 Aug 25 07:10 cpuinfo_min_freq
-r--r--r--. 1 root root 4096 Aug 25 07:10 cpuinfo_transition_latency
-r--r--r--. 1 root root 4096 Aug 25 07:10 related_cpus
-r--r--r--. 1 root root 4096 Aug 25 07:10 scaling_available_governors
-r--r--r--. 1 root root 4096 Aug 25 07:10 scaling_cur_freq
-r--r--r--. 1 root root 4096 Aug 25 07:10 scaling_driver
-rw-r--r--. 1 root root 4096 Aug 25 07:10 scaling_governor
-rw-r--r--. 1 root root 4096 Aug 25 07:10 scaling_max_freq
-rw-r--r--. 1 root root 4096 Aug 25 07:10 scaling_min_freq
-rw-r--r--. 1 root root 4096 Aug 25 07:10 scaling_setspeed

I also have those.

# ls -l /sys/devices/system/cpu/cpu*/cpufreq
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu0/cpufreq -> ../cpufreq/policy0
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu10/cpufreq -> ../cpufreq/policy10
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu11/cpufreq -> ../cpufreq/policy11
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu1/cpufreq -> ../cpufreq/policy1
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu2/cpufreq -> ../cpufreq/policy2
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu3/cpufreq -> ../cpufreq/policy3
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu4/cpufreq -> ../cpufreq/policy4
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu5/cpufreq -> ../cpufreq/policy5
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu6/cpufreq -> ../cpufreq/policy6
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu7/cpufreq -> ../cpufreq/policy7
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu8/cpufreq -> ../cpufreq/policy8
lrwxrwxrwx. 1 root root 0 Aug 17 21:00 /sys/devices/system/cpu/cpu9/cpufreq -> ../cpufreq/policy9
# ls -l /sys/devices/system/cpu/cpufreq/policy0
total 0
-r--r--r--. 1 root root 4096 Aug 19 08:33 affected_cpus
-r--r--r--. 1 root root 4096 Aug 25 09:20 bios_limit
-rw-r--r--. 1 root root 4096 Aug 19 08:33 cpb
-r--------. 1 root root 4096 Aug 19 08:33 cpuinfo_cur_freq
-r--r--r--. 1 root root 4096 Aug 17 21:00 cpuinfo_max_freq
-r--r--r--. 1 root root 4096 Aug 19 08:33 cpuinfo_min_freq
-r--r--r--. 1 root root 4096 Aug 25 08:30 cpuinfo_transition_latency
-r--r--r--. 1 root root 4096 Aug 25 09:20 freqdomain_cpus
-r--r--r--. 1 root root 4096 Aug 25 08:30 related_cpus
-r--r--r--. 1 root root 4096 Aug 25 08:30 scaling_available_frequencies
-r--r--r--. 1 root root 4096 Aug 25 08:30 scaling_available_governors
-r--r--r--. 1 root root 4096 Aug 19 08:33 scaling_cur_freq
-r--r--r--. 1 root root 4096 Aug 25 08:30 scaling_driver
-rw-r--r--. 1 root root 4096 Aug 25 08:30 scaling_governor
-rw-r--r--. 1 root root 4096 Aug 19 08:33 scaling_max_freq
-rw-r--r--. 1 root root 4096 Aug 19 08:33 scaling_min_freq
-rw-r--r--. 1 root root 4096 Aug 25 09:20 scaling_setspeed
drwxr-xr-x. 2 root root    0 Aug 25 08:27 stats

since the /sys/devices/system/cpu/cpu0/cpufreq is a symlink to /sys/devices/system/cpu/cpufreq/policy0/ I think you are reading that incorrectly. The stats subdir is under the latter.

# ls -l /sys/devices/system/cpu/cpu0/cpufreq/stats
total 0
--w-------. 1 root root 4096 Aug 25 09:23 reset
-r--r--r--. 1 root root 4096 Aug 25 09:23 time_in_state
-r--r--r--. 1 root root 4096 Aug 25 09:23 total_trans
-r--r--r--. 1 root root 4096 Aug 25 09:23 trans_table


# ls -l /sys/devices/system/cpu/cpufreq/policy0/stats
total 0
--w-------. 1 root root 4096 Aug 25 09:23 reset
-r--r--r--. 1 root root 4096 Aug 25 09:23 time_in_state
-r--r--r--. 1 root root 4096 Aug 25 09:23 total_trans
-r--r--r--. 1 root root 4096 Aug 25 09:23 trans_table