Linux thermal框架的cpu_cooling子系统通过cpufreq_cooling实现基于
频率调整的CPU热冷却机制。核心结构体是cpufreq_cooling_device,它
将cpufreq频率调节能力抽象为thermal的冷却设备(cooling device)。
cpufreq_cooling注册入口是cpufreq_cooling_register(),接收cpufreq_policy
参数,返回struct thermal_cooling_device:
```c
struct thermal_cooling_device *
cpufreq_cooling_register(struct cpufreq_policy *policy)
{
struct cpufreq_cooling_device *cpufreq_cdev;
struct thermal_cooling_device *cdev;
int ret;
// 分配cpufreq冷却设备结构体
cpufreq_cdev = kzalloc(sizeof(*cpufreq_cdev), GFP_KERNEL);
if (!cpufreq_cdev)
return ERR_PTR(-ENOMEM);
// 获取CPU频率表并初始化OPP
cpufreq_cdev->policy = policy;
cpufreq_cdev->max_level = cpufreq_cdev->freq_table->size - 1;
// 注册为热冷却设备
cdev = thermal_cooling_device_register("cpufreq", cpufreq_cdev,
&cpufreq_cooling_ops);
if (IS_ERR(cdev)) {
kfree(cpufreq_cdev);
return cdev;
}
cpufreq_cdev->cdev = cdev;
return cdev;
}
```
cpufreq_cooling_ops定义了冷却设备的三个核心操作:
```c
static struct thermal_cooling_device_ops cpufreq_cooling_ops = {
.get_max_state = cpufreq_get_max_state, // 获取最大冷却级别
.get_cur_state = cpufreq_get_cur_state, // 获取当前冷却级别
.set_cur_state = cpufreq_set_cur_state, // 设置冷却级别
};
```
set_cur_state是频率限制的关键函数,它根据传入的冷却级别(cooling state)
映射到对应的CPU频率上限:
```c
static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long state)
{
struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
struct cpufreq_policy *policy = cpufreq_cdev->policy;
unsigned int clip_freq;
// 状态0表示无冷却限制,使用最高频率
// 状态值越大,冷却越强,频率越低
if (state == 0) {
clip_freq = policy->cpuinfo.max_freq;
} else {
// 根据冷却级别查表得到限制频率
// state=1限制到次高频率,state=max_level限制到最低频率
int index = cpufreq_cdev->max_level - state;
clip_freq = cpufreq_cdev->freq_table[index].frequency;
}
// 通过cpufreq设置新的频率上限
// 防止CPU频率超过clip_freq
cpufreq_verify_within_limits(policy,
policy->cpuinfo.min_freq, clip_freq);
// 触发频率调节
cpufreq_update_policy(policy->cpu);
// 更新当前状态计数器
cpufreq_cdev->cpufreq_state = state;
return 0;
}
```
冷却级别与CPU频率的映射关系由频率表定义。每个冷却级别对应一个
最大允许频率,级别0无限制,最高级别将CPU锁定在最低频率:
```c
static int cpufreq_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
// 最大状态数 = 可用频率级别数 - 1
*state = cpufreq_cdev->max_level;
return 0;
}
static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
// 返回当前冷却级别
*state = cpufreq_cdev->cpufreq_state;
return 0;
}
```
cpufreq_cooling还提供了power-aware接口,通过cpufreq_power2state()
将功耗需求转换为对应的冷却级别。power_allocator governor使用该接口
实现PID控制器驱动的精确功率控制:
```c
int cpufreq_power2state(struct thermal_cooling_device *cdev,
struct em_perf_state *table,
u32 power, unsigned long *state)
{
struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
int i;
u32 freq, power_at_freq;
// 从功耗模型中查找对应给定功率的最高频率
for (i = cpufreq_cdev->max_level; i >= 0; i--) {
freq = cpufreq_cdev->freq_table[i].frequency;
power_at_freq = table[i].power;
if (power_at_freq <= power)
break;
}
// 转换为冷却状态
*state = cpufreq_cdev->max_level - i;
return 0;
}
```
cpufreq_cooling与thermal governor的联动:当thermal_zone温度超过
passive trip点时,governor调用set_cur_state逐步降低频率;温度回落
后逐步升高频率。频率的实际调节由cpufreq驱动完成,cpufreq_cooling只
设置上限,实际频率由cpufreq governor(如schedutil)在限制范围内选择。
cpufreq_cooling_unregister()在模块卸载时调用,清理频率表和冷却设备。
在ARM平台上,cpu_cooling通常与cpufreq驱动(如cpufreq-dt)配合使用,
通过设备树的thermal-zones节点配置频率冷却映射关系。
Linux cpu_cooling热电冷却与频率限制cpufreq_cooling
张小明
前端开发工程师
ECG模型:统一压缩与分组的向量表征学习,优化RAG检索效率与精度
1. 项目概述:当RAG遇上“心电图”,一次关于效率与精度的深度手术最近在折腾RAG(检索增强生成)项目时,我被一个老问题反复折磨:检索效率与精度之间的永恒博弈。传统的双塔模型(如DPR)…
Ubuntu 18.04 SSH密钥配置实战:RSA 3072+VS Code远程开发零故障
1. 项目概述:为什么在 Ubuntu 18.04 上配置 SSH 密钥不是“可选项”,而是“必修课”你刚在阿里云或腾讯云上开了一台 Ubuntu 18.04 的轻量应用服务器,想用 VS Code 的 Remote-SSH 插件连上去写代码,结果第一次输入ssh useryour-se…
东莞翻译公司 英语公司章程翻译要点
最近因为公司业务拓展,需要将一份中文公司章程翻译成英语,用于海外注册和合作。我在东莞找了几家翻译公司对比,才发现公司章程翻译看似简单,实则有不少门道。公司章程涉及法律条款、公司治理结构、股东权益等专业内容,…
Redis 持久化文件重写机制详解
Redis 持久化文件重写机制详解 Redis作为高性能的内存数据库,持久化机制是其数据安全的核心保障。其中,文件重写机制(Rewrite)是优化AOF(Append-Only File)持久化效率的关键技术。通过重写,Red…
深度强化学习嵌入空间可视化与UMAP降维实践
1. 项目背景与核心问题在深度强化学习(DRL)研究中,理解智能体如何通过神经网络内部表征进行决策一直是个黑箱问题。传统方法往往只关注最终策略表现,而忽略了嵌入空间的结构特性。我们团队在分析基于Transformer架构的DRL模型时发…
开发日志(十六):测试调试、拍照识别与数据库问题修复
前言 在本阶段的项目开发中,我主要围绕“点单翻译”系统进行了测试、调试和问题修复工作。项目的核心功能是帮助用户通过拍照或上传菜单图片,快速识别菜单内容,并结合个人口味偏好、过敏原、收藏记录等信息,为用户提供更智能的点…