Linux cpupower 的 frequency-set 与 governor 动态调整脚本

1次阅读

cpupower frequency-set 设不生效的根本原因是当前 governor 不支持手动设频,仅 userspace 和 performance 支持,但 performance 不响应 -f;需先切 userspace 再设频,且须确认驱动与权限。

Linux cpupower 的 frequency-set 与 governor 动态调整脚本

cpupower frequency-set 命令为什么设不生效?

根本原因通常是当前 governor 不支持手动频率设定。比如 ondemandconservative 这类动态 governor 会忽略你用 frequency-set -f 强设的值,只按负载自动调节;只有 userspaceperformance 才真正响应 -f 参数。

实操建议:

  • 先用 cpupower frequency-info 确认当前 governor 和可用频率范围
  • 若想固定频率,必须先切到 userspacecpupower frequency-set -g userspace
  • 再设目标频率:cpupower frequency-set -f 2.4GHz(注意单位支持 GHzMHzkHz,但部分内核版本不识别 GHz,建议统一用 MHz
  • performance governor 虽默认跑最高频,但它不接受 -f,强行设会报错 Setting cpu frequency failed

如何写一个安全切换 governor + 频率的 shell 脚本?

关键不是“能跑”,而是避免把系统卡死——比如在笔记本上误设 performance 导致风扇狂转,或在虚拟机里调 userspace 却没权限写 sysfs。

实操建议:

  • 脚本开头加权限检查:if ! cpupower frequency-info &>/dev/NULL; then echo "cpupower not available"; exit 1; fi
  • 对每个 CPU 核单独处理(尤其多 socket 服务器),用 for cpu in /sys/devices/system/cpu/cpu[0-9]*; do
  • 切换前保存原 governor:orig_gov=$(cat $cpu/cpufreq/scaling_governor 2>/dev/null),退出时可还原
  • 设频率前确认该 governor 支持手动设置:仅当 userspacescaling_available_governors 里且当前是它,才执行 frequency-set -f
  • 避免用 sudo 全局提权,改用 sudo cpupower ... 按需调用

为什么脚本在 systemd service 里运行失败?

常见现象是日志里出现 Permission deniedNo such file or Directory,本质是 systemd 默认限制了对 /sys/devices/system/cpu/ 的访问,且 cpupower 初始化依赖 udev 规则未就绪。

实操建议:

  • service 文件里加 WantedBy=multi-user.targetAfter=sysinit.target,确保 CPU 频率子系统已加载
  • 必须显式声明权限:CapabilityBoundingSet=CAP_SYS_ADMINRestrictDevices=false
  • 不要依赖环境变量(如 $PATH),用绝对路径调用:/usr/bin/cpupower frequency-set
  • 测试时先用 systemctl --no-block start your-service,再立刻 journalctl -u your-service -n 20 查错

governor 切换后频率没变,是 bug 吗?

不是 bug,是预期行为。比如从 powersave 切到 performance,内核不会立刻跳到 max freq,而是等下一个 tick 或负载上升时才触发升频;同理,切回 ondemand 后,当前频率可能维持几秒不变。

实操建议:

  • watch -n 1 'grep "cur" /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq' 实时观察实际频率
  • 验证 governor 是否生效,看 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 内容是否更新,别只信 cpupower frequency-info 缓存输出
  • 某些 Intel CPU(如带 Speed Shift 的 Skylake+)默认用 intel_pstate 驱动,此时 cpupower 对 governor 的控制力有限,需检查 cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver 输出是不是 intel_pstate

最常被忽略的一点:不同 CPU 架构(x86 vs ARM)、不同内核驱动(acpi-cpufreq vs intel_pstate)下,cpupower 的行为差异极大,同一脚本在笔记本和云服务器上可能一个生效一个静默失败。动手前先看 scaling_driver,比背参数重要得多。

text=ZqhQzanResources