如何在内核代码中获取当前CPU频率?及/proc/cpuinfo查询无变化问题
内核中获取CPU频率的实现方案
1. 调用cpufreq核心接口
内核cpufreq子系统提供了标准API用于获取CPU频率,核心函数如下:
- 获取当前CPU实时频率:使用
cpufreq_get_current_freq(),需包含头文件<linux/cpufreq.h>。调用时必须绑定到目标CPU并禁止抢占,避免调度导致的CPU切换:
#include <linux/cpufreq.h> #include <linux/smp.h> unsigned int get_cpu_real_freq(unsigned int cpu) { unsigned int freq = 0; if (!cpu_online(cpu)) return freq; get_cpu(); // 锁定当前CPU,禁止抢占 freq = cpufreq_get_current_freq(); put_cpu(); // 释放CPU锁 return freq; }
- 获取CPU频率策略信息:如果需要最小、最大频率等完整参数,可通过
cpufreq_cpu_get()获取struct cpufreq_policy结构体:
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); if (policy) { pr_info("CPU%d: min=%u kHz, max=%u kHz, current=%u kHz\n", cpu, policy->min, policy->max, policy->cur); cpufreq_cpu_put(policy); // 必须释放policy实例 }
2. 编译与配置要求
- 模块Makefile需确保链接cpufreq相关依赖,内核配置必须开启
CONFIG_CPU_FREQ(可通过make menuconfig在Power management options → CPU Frequency scaling中开启)。 - 部分架构需要额外启用对应驱动,比如x86的
CONFIG_X86_ACPI_CPUFREQ、ARM的CONFIG_ARM_CPUFREQ。
/proc/cpuinfo中cpu MHz无变化的问题分析
1. 核心原因
- Governor模式为performance:该模式下CPU固定运行在最高频率,
cpu MHz自然不会变动。可通过cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor确认。 - cpufreq子系统未启用:内核未开启
CONFIG_CPU_FREQ或未加载对应调频驱动,导致无法动态调整频率。 - /proc/cpuinfo显示标称频率:部分旧内核或特定架构中,
cpu MHz字段仅显示CPU的标称最大频率,而非实时运行频率。 - 系统负载不足:即使使用ondemand/powersave等动态governor,低负载下CPU可能维持在固定低频率,无波动。
2. 验证与解决
- 查看实时频率:直接读取sysfs的实时频率文件,该值是动态更新的:
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
- 切换动态Governor:将governor改为ondemand或schedutil,触发动态调频:
echo ondemand | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
- 检查内核配置:确保
CONFIG_CPU_FREQ及对应驱动已开启,必要时重新编译内核。
内容的提问来源于stack exchange,提问作者liuye
相关产品推荐
相关产品推荐

