You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核模块中cpufreq_get返回0的问题求助

解决cpufreq_get()返回0的问题

看起来你在调用内核API cpufreq_get(3) 获取CPU频率时遇到了返回0的问题,结合你提到的内核配置正常、sysfs能读取频率的信息,咱们一步步来排查解决:

1. 先确认目标CPU是否存在且在线

首先要确保系统里真的有CPU3——CPU编号是从0开始计数的,你可以通过cat /proc/cpuinfo查看系统的CPU总数。如果你的系统CPU数量不足4,那调用cpufreq_get(3)自然会返回无效值(比如0)。

就算CPU存在,也要检查它是否处于在线状态,离线CPU的cpufreq policy不会被初始化,调用cpufreq_get()也会返回0。

2. 改用更可靠的policy读取方式

cpufreq_get()内部其实是获取目标CPU的cpufreq policy结构,然后返回policy->cur,但它没有做任何错误检查。如果policy未初始化,就会返回0。咱们可以手动做检查,代码示例如下:

#include <linux/cpufreq.h>
#include <linux/smp.h>

void func() {
    struct cpufreq_policy *policy;
    const unsigned int target_cpu = 3;

    // 第一步:检查CPU是否在线
    if (!cpu_online(target_cpu)) {
        printk(KERN_ALERT "CPU %u is not online\n", target_cpu);
        return;
    }

    // 第二步:获取cpufreq policy
    policy = cpufreq_get_policy(target_cpu);
    if (!policy) {
        printk(KERN_ALERT "Failed to retrieve cpufreq policy for CPU %u\n", target_cpu);
        return;
    }

    // 第三步:读取当前频率
    printk(KERN_ALERT "CPU %u Freq in KHz: %u\n", target_cpu, policy->cur);
}

这种方式能明确排查出是CPU离线还是policy未初始化的问题,比直接调用cpufreq_get()更健壮。

3. 检查模块的加载时机与依赖

如果你的内核模块是在系统启动早期加载的,此时cpufreq子系统可能还没完成所有CPU的policy初始化。可以尝试:

  • 先手动加载cpufreq模块:modprobe cpufreq,再加载你的自定义模块
  • 在模块代码中确保初始化逻辑在cpufreq子系统就绪后执行(比如使用late_initcall()替代module_init())

4. Intel P-State驱动的特殊情况

因为你启用了CONFIG_X86_INTEL_PSTATE=y,Intel P-State驱动在某些模式下(比如主动模式),cpufreq的policy->cur可能不会实时更新,但sysfs能正常读取说明驱动工作正常。如果需要更直接的方式,也可以通过读取MSR寄存器获取频率(需要开启CONFIG_X86_MSR=y):

#include <asm/msr.h>

unsigned int get_intel_cpu_freq_khz(unsigned int cpu) {
    uint64_t msr_val;
    unsigned int core_ratio, bus_freq;

    // 读取当前核心倍频(MSR_IA32_PERF_STATUS)
    rdmsrl_on_cpu(cpu, MSR_IA32_PERF_STATUS, &msr_val);
    core_ratio = (msr_val >> 0) & 0xffff;
    // 读取基准总线频率(这里假设是100MHz,部分CPU可能不同)
    // 也可以通过MSR_IA32_PERF_CTL读取,或者从sysfs获取总线频率
    bus_freq = 100;

    return core_ratio * bus_freq; // 转换为KHz
}

不过这种方法需要注意CPU型号的兼容性,不同Intel CPU的MSR定义可能有差异。

总结

最稳妥的方案是先检查CPU在线状态,再获取cpufreq policy并读取频率,这样能有效避免因CPU离线或policy未初始化导致的返回0问题。

内容的提问来源于stack exchange,提问作者sal_guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:56:52