Score:1

cpufreq-set not taking effect on fixing CPU frequency on ubuntu 20

cn flag

I need to set a fixed frequency on my CPUs for a research project.

I'm using Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-155-generic x86_64) and an intel CPU Xeon W-2155 3.3GHz.

I'm trying to use the cpufrequtils package to do that. Governor is powersave.

$ cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
powersave
powersave
powersave
powersave
powersave
powersave
powersave
powersave
powersave
powersave

As far as I know, I can set the frequency with the -d (min. freq.) and -u (max. freq.) cpufreq-set arguments. I run:

sudo cpufreq-set -c 0 -d 1.8GHz -u 1.8GHz

To set CPU 0 frequency to 1.8GHz.

Then if I run cpufreq-info, I see that the limits are set, but they are not taking effect.

analyzing CPU 0:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 4294.55 ms.
  hardware limits: 1.20 GHz - 4.50 GHz
  available cpufreq governors: performance, powersave
  current policy: frequency should be within 1.80 GHz and 1.80 GHz.
                  The governor "powersave" may decide which speed to use
                  within this range.
  current CPU frequency is 1.31 GHz.

Why the current CPU frequency is out of the governor limits? I used a similar approach in another server/cpu (i7-7700K 4.2GHz, though) and got the desired frequency fixed.

(Similar question here, but it was not solved.)

guiverc avatar
cn flag
I'll suggest applying security fixes to your system asap, as a fully upgraded Ubuntu 20.04 LTS system will report as 20.04.6 and not 20.04.5. (You can refer to https://fridge.ubuntu.com/2023/03/23/ubuntu-20-04-6-lts-released/ for the ISO release date, but installed systems upgraded late in the week before that date)
Doug Smythies avatar
gn flag
When CPU 0 is in a deep idle state its requirements are not included in the decision as to what the overall CPU frequency will be. Try setting all CPUs min and max to the same 1.8 GHz. Be aware that even then the processor itself might back off the CPU frequency if all CPUs are in a deep idle state.
exepe avatar
cn flag
Thank you for the comments. Setting all CPUs to the same max and min limits didn't work. I could, however, disable intel_pstate during the boot (adjusting the GRUB_CMDLINE_LINUX_DEFAULT="intel_pstate=disable") in /etc/default/grub, then grup-update, then reboot, relying on the acpi-cpufreq driver. In this case my commands to set the frequency worked.
Doug Smythies avatar
gn flag
Well, the feedback information you are getting from the acpi-cpufreq driver is misleading, because when a frequency is stale due to the CPU being in an idle state it just reports the CPU frequency that was asked for and not the actual CPU frequency. In terms of real feedback and really knowing what is actually going on, you would do better to stay with the intel_pstate CPU frequency scaling driver.
exepe avatar
cn flag
My interest in fixed frequency is to take measurements during the execution of an application, where the CPU would not be idle. Would the information be trustworthy in that case? (The execution frequency would be the one I asked acpi-cpufreq?)
Doug Smythies avatar
gn flag
Actually, I have spent time on your issue. I went back to kernel 5.4.0-156-generic and get similar to your results from your i7-7700K 4.2GHz on my i5-10600K. Back then, and for the intel_pstate driver the CPU would be woken from idle just to read the CPU frequency. Since then things have changed and the CPU is not woken from idle just to read the CPU frequency. The difference for your Xeon W-2155 might be a slower PLL (Phased Locked Loop) settling time or some sort of throttling being involved. If not idle, the info from the intel_pstate driver should be trustworthy.
Score:1
gn flag

For the generations of Intel processors of the question, there is only one CPU clock generator for all CPUs, driven by a Phase Locked Loop, PLL. The PLL takes a finite amount of time to ramp up or down to whatever CPU frequency it decides to generate. CPUs in deep idle states relinquish their vote as to desired CPU frequency. Other CPUs requesting a higher CPU frequency can override the max frequency of another.

To always generate 1.8GHz CPU frequency, the min and max frequency for all CPUs needs to be set to that value AND deep idle states need to be disabled for at least one CPU (at the cost of power) such that there always at least one CPU submitting a vote request to the PLL for pstate 18 (at 100MHz per pstate). Example using CPU 5 as my test CPU:

doug@s19:~$ echo 1800000 | sudo tee /sys/devices/system/cpu/cpufreq/policy*/scaling_max_freq
1800000
doug@s19:~$ grep . /sys/devices/system/cpu/cpufreq/policy*/scaling_max_freq
/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy10/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy11/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy1/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy2/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy3/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy5/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy6/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy7/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy8/scaling_max_freq:1800000
/sys/devices/system/cpu/cpufreq/policy9/scaling_max_freq:1800000
doug@s19:~$ echo 1800000 | sudo tee /sys/devices/system/cpu/cpufreq/policy*/scaling_min_freq
1800000
doug@s19:~$ grep . /sys/devices/system/cpu/cpufreq/policy*/scaling_min_freq
/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy10/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy11/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy1/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy2/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy3/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy5/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy6/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy7/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy8/scaling_min_freq:1800000
/sys/devices/system/cpu/cpufreq/policy9/scaling_min_freq:1800000
doug@s19:~/idle$ grep . /sys/devices/system/cpu/cpu5/cpuidle/state*/name
/sys/devices/system/cpu/cpu5/cpuidle/state0/name:POLL
/sys/devices/system/cpu/cpu5/cpuidle/state1/name:C1
/sys/devices/system/cpu/cpu5/cpuidle/state2/name:C2
/sys/devices/system/cpu/cpu5/cpuidle/state3/name:C3
doug@s19:~/idle$ grep . /sys/devices/system/cpu/cpu5/cpuidle/state*/disable
/sys/devices/system/cpu/cpu5/cpuidle/state0/disable:0
/sys/devices/system/cpu/cpu5/cpuidle/state1/disable:0
/sys/devices/system/cpu/cpu5/cpuidle/state2/disable:0
/sys/devices/system/cpu/cpu5/cpuidle/state3/disable:0
doug@s19:~/idle$ echo 1 | sudo tee /sys/devices/system/cpu/cpu5/cpuidle/state1/disable
1
doug@s19:~/idle$ echo 1 | sudo tee /sys/devices/system/cpu/cpu5/cpuidle/state2/disable
1
doug@s19:~/idle$ echo 1 | sudo tee /sys/devices/system/cpu/cpu5/cpuidle/state3/disable
1
doug@s19:~/idle$ grep . /sys/devices/system/cpu/cpu5/cpuidle/state*/disable
/sys/devices/system/cpu/cpu5/cpuidle/state0/disable:0
/sys/devices/system/cpu/cpu5/cpuidle/state1/disable:1
/sys/devices/system/cpu/cpu5/cpuidle/state2/disable:1
/sys/devices/system/cpu/cpu5/cpuidle/state3/disable:1

Note: Your number of idle states might be different. Just disable all except state 0. Now observe the CPU frequencies:

doug@s19:~/idle$ grep . /sys/devices/system/cpu/cpufreq/policy*/scaling_cur_freq
/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq:1801307
/sys/devices/system/cpu/cpufreq/policy10/scaling_cur_freq:1800484
/sys/devices/system/cpu/cpufreq/policy11/scaling_cur_freq:1801825
/sys/devices/system/cpu/cpufreq/policy1/scaling_cur_freq:1800432
/sys/devices/system/cpu/cpufreq/policy2/scaling_cur_freq:1801306
/sys/devices/system/cpu/cpufreq/policy3/scaling_cur_freq:1803848
/sys/devices/system/cpu/cpufreq/policy4/scaling_cur_freq:1800934
/sys/devices/system/cpu/cpufreq/policy5/scaling_cur_freq:1800000
/sys/devices/system/cpu/cpufreq/policy6/scaling_cur_freq:1801484
/sys/devices/system/cpu/cpufreq/policy7/scaling_cur_freq:1799961
/sys/devices/system/cpu/cpufreq/policy8/scaling_cur_freq:1800669
/sys/devices/system/cpu/cpufreq/policy9/scaling_cur_freq:1799992

Use turbostat (linux_tools_common package, I think) to monitor:

$ sudo turbostat --Summary --quiet --show Busy%,Bzy_MHz,IRQ,PkgWatt,PkgTmp,RAMWatt,GFXWatt,CorWatt --interval 10
Busy%   Bzy_MHz IRQ     PkgTmp  PkgWatt CorWatt GFXWatt RAMWatt
8.32    1800    2910    38      3.27    2.62    0.00    1.33
8.32    1800    2757    38      3.19    2.53    0.00    1.33
8.32    1800    2750    39      2.99    2.33    0.00    1.33

Note: This answer was written using kernel 5.4.0-156-generic, to be similar to what the question was using. Readers using more recent kernels will get different results for actual frequencies because things have changed and idle CPUs are no longer woken just to read the frequency. A default is returned in that case. Example using kernel 6.5:

doug@s19:~$ grep . /sys/devices/system/cpu/cpufreq/policy*/scaling_cur_freq
/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq:4100000
/sys/devices/system/cpu/cpufreq/policy10/scaling_cur_freq:1800006
/sys/devices/system/cpu/cpufreq/policy11/scaling_cur_freq:4100000
/sys/devices/system/cpu/cpufreq/policy1/scaling_cur_freq:1799751
/sys/devices/system/cpu/cpufreq/policy2/scaling_cur_freq:4100000
/sys/devices/system/cpu/cpufreq/policy3/scaling_cur_freq:4100000
/sys/devices/system/cpu/cpufreq/policy4/scaling_cur_freq:1799571
/sys/devices/system/cpu/cpufreq/policy5/scaling_cur_freq:1799995
/sys/devices/system/cpu/cpufreq/policy6/scaling_cur_freq:4100000
/sys/devices/system/cpu/cpufreq/policy7/scaling_cur_freq:4100000
/sys/devices/system/cpu/cpufreq/policy8/scaling_cur_freq:1800304
/sys/devices/system/cpu/cpufreq/policy9/scaling_cur_freq:1800337

where the 4.1 GHz number is a default for an idle CPU. Note that that is above the 1.8GHz max we set. That will change to the current min in future.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.