wordpress 表单插件绍兴seo包年排行榜
原文:蜗窝科技linux thermal framework(4)_thermal governor
1. 介绍
thermal governor是通过一定算法控制cooling device状态来控温的在这篇文章中,我们使用一个简单的step_wise governor来说明整个过程。
2. thermal governor相关的API以及功能分析
2.1 struct thermal_governor
/*** struct thermal_governor - structure that holds thermal governor information* @name: name of the governor* @bind_to_tz: callback called when binding to a thermal zone. If it* returns 0, the governor is bound to the thermal zone,* otherwise it fails.* @unbind_from_tz: callback called when a governor is unbound from a* thermal zone.* @throttle: callback called for every trip point even if temperature is* below the trip point temperature* @governor_list: node in thermal_governor_list (in thermal_core.c)*/struct thermal_governor {//1)name, 每个governor会有一个名字,在温控的governors中,常见的有power_allocator/userspace/step_wisechar name[THERMAL_NAME_LENGTH];//2)bind_to_tz, governor绑定thermal_zone的回调函数int (*bind_to_tz)(struct thermal_zone_device *tz);//3)unbind_from_tz,governor和thermal_zone解绑的回调函数void (*unbind_from_tz)(struct thermal_zone_device *tz);int (*throttle)(struct thermal_zone_device *tz, int trip);//4)governor_list,thermal core通过一个链表来管理所有的governors,这个是该governor在链表中的节点struct list_head governor_list;ANDROID_KABI_RESERVE(1);};
2.2 thermal_governor的注册
linux在lds中静态定义了一个governor_thermal_table,每个thermal governor会在这个table中添加一个entry,以step_wise为例:
kernel-6.6/drivers/thermal/gov_step_wise.c
/** 如果内核配置启用了 THERMAL(温度控制模块),则定义 THERMAL_TABLE 宏,* 否则定义为空(避免未启用时产生无效代码)*/#ifdef CONFIG_THERMAL/** THERMAL_TABLE 宏定义:* 用于在内存中按 8 字节对齐方式放置温度控制相关的数据表,* 并通过 BOUNDED_SECTION_POST_LABEL 标记其起始和结束地址*/#define THERMAL_TABLE(name) \. = ALIGN(8); /* 按 8 字节对齐当前地址 */ \BOUNDED_SECTION_POST_LABEL(__##name##_thermal_table, /* 定义符号表起始 */ \__##name##_thermal_table,, _end) /* _end 表示结束位置 */#else/* 如果未启用 THERMAL,则 THERMAL_TABLE 宏不执行任何操作 */#define THERMAL_TABLE(name)#endif/** 定义 step_wise 温控策略的结构体:* 该策略通过逐步调整冷却设备(如风扇/CPU调频)来控制温度*/static struct thermal_governor thermal_gov_step_wise = {.name = "step_wise", /* 策略名称(用于匹配和调试) */.manage = step_wise_manage, /* 核心管理函数指针,实现温度调节逻辑 */};/** 向内核注册此温控策略:* THERMAL_GOVERNOR_DECLARE 宏会将结构体放入特定内存段(如 __thermal_governor),* 供内核初始化时调用*/THERMAL_GOVERNOR_DECLARE(thermal_gov_step_wise);
thermal core在初始化的过程中,会遍历governor_thermal_table中所有的entry,即所有的governor,将其加进governor_list中,比较这个governor和DEFAULT_THERMAL_GOVERNOR名字是否想同,相同的话,就将系统默认的governor设置为这个governor,遍历所有的thermal_zone,如果这个governor的名字和thermal zone本身有的governor名字相同,则会设置thermal zone的governor
对governor来说,主要的回调函数就是manage,manage会在thermal zone拥有的monitor每次check thermal zone的温度的时候调用该thermal zone对应的governor->manage函数,我们可以看下step_wise的manage函数是怎么调温的
2.3 step_wise温控算法
首先我们还是用这张图结合stepwise的算法来描述以下过程:

/*** step_wise_manage - 温控策略核心管理函数(逐步调节)* @tz: 指向 thermal_zone_device 的指针,代表一个温度监控区域** 功能:根据温度变化趋势逐步调整冷却设备状态(如风扇转速/CPU频率)。* 若温度上升,则逐级增强冷却;若温度下降,则逐级恢复性能。*/static void step_wise_manage(struct thermal_zone_device *tz){const struct thermal_trip_desc *td; // 温度触发点描述符struct thermal_instance *instance; // 冷却设备实例/* 锁断言:确保调用时已持有温度区域的锁 */lockdep_assert_held(&tz->lock);/** 核心调节逻辑:* 1. 遍历所有温度触发点(trip point),跳过无效/危险温度点* 2. 对每个有效触发点,更新其关联冷却设备的阈值状态* 3. 最终统一更新所有冷却设备状态*/for_each_trip_desc(tz, td) {const struct thermal_trip *trip = &td->trip;/* 跳过以下触发点:* - 未配置有效温度值(THERMAL_TEMP_INVALID)* - 关键温度(CRITICAL,可能触发紧急关机)* - 过热温度(HOT,可能触发强制降频)*/if (trip->temperature == THERMAL_TEMP_INVALID ||trip->type == THERMAL_TRIP_CRITICAL ||trip->type == THERMAL_TRIP_HOT)continue;/* 更新当前触发点的温度状态(根据趋势调整阈值) */thermal_zone_trip_update(tz, td, td->threshold);}/* 遍历所有触发点及其关联的冷却设备实例 */for_each_trip_desc(tz, td) {list_for_each_entry(instance, &td->thermal_instances, trip_node)/* 通知冷却设备更新状态(如调整风扇档位) */thermal_cdev_update(instance->cdev);}}
1)首先遍历这个thermal zone所有的trip:for_each_trip_desc,过滤掉其中无效或者档位过高的trip,然后调用thermal_zone_trip_update这个函数来更新trip信息,为选择最佳cooling device state做准备
2)在做好更新后,重新遍历trip,thermal_c
继续看下thermal_zone_trip_update是如何更新trip信息的:
kernel-6.6/drivers/thermal/gov_step_wise.c
/*** thermal_zone_trip_update - 更新温控触发点状态并调整冷却设备* @tz: 指向thermal_zone_device的指针,代表一个温度监控区域* @trip_id: 要处理的温度触发点ID** 功能:根据温度趋势和当前温度与触发点的关系,动态调整冷却设备状态* 支持被动冷却(如CPU降频)和主动冷却(如风扇调速)两种模式*/static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id){// 获取指定触发点的配置信息const struct thermal_trip *trip = &tz->trips[trip_id];enum thermal_trend trend; // 温度变化趋势(上升/下降/稳定)struct thermal_instance *instance; // 冷却设备实例bool throttle = false; // 是否需要抑制性能的标志int old_target; // 保存设备之前的控制状态// 获取温度变化趋势(通过历史温度数据分析)trend = get_tz_trend(tz, trip_id);/* 基础节流判断:当前温度超过触发温度时激活节流 */if (tz->temperature >= trip->temperature) {throttle = true;// 记录跟踪点(用于ftrace等性能分析工具)trace_thermal_zone_trip(tz, trip_id, trip->type);}/* 调试日志:打印触发点关键参数 */dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",trip_id, trip->type, trip->temperature, trend, throttle);/* 遍历该温控区域下的所有冷却设备实例 */list_for_each_entry(instance, &tz->thermal_instances, tz_node) {// 跳过不属于当前触发点的实例if (instance->trip != trip)continue;// 保存当前状态用于后续比较old_target = instance->target;// 计算新目标状态(考虑温度趋势和节流需求)instance->target = get_target_state(instance, trend, throttle);/* 调试日志:显示状态变化 */dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",old_target, (int)instance->target);/* 跳过无变化且已初始化的实例(优化性能) */if (instance->initialized && old_target == instance->target)continue;/** 被动冷却处理(如CPU调频):* 当设备从未激活状态变为激活时,增加被动冷却计数*/if (old_target == THERMAL_NO_TARGET &&instance->target != THERMAL_NO_TARGET)update_passive_instance(tz, trip->type, 1); // 增加计数/** 当设备从激活状态变为未激活时,减少被动冷却计数*/else if (old_target != THERMAL_NO_TARGET &&instance->target == THERMAL_NO_TARGET)update_passive_instance(tz, trip->type, -1); // 减少计数// 标记实例已完成初始化instance->initialized = true;/* 标记冷却设备需要更新状态 */mutex_lock(&instance->cdev->lock);instance->cdev->updated = false; // 触发后续thermal_cdev_update()mutex_unlock(&instance->cdev->lock);}}
1)trend = get_tz_trend,首先得到温度趋势,上升:THERMAL_TREND_RAISING or 下降:THERMAL_TREND_DROPPING
2)throttle:是否达到trip限制的温度
3)遍历这个trip所有的thermal instances,调用get_target_state获得目标状态,如果目标状态和原有状态不同,就设置cooling device的update参数为false,在后面的函数中更新为target state
get_target_state是获取目标状态的主函数:
/*** get_target_state - 根据温度趋势和节流需求计算冷却设备的目标状态* @instance: 温控实例(关联特定触发点和冷却设备)* @trend: 当前温度变化趋势(上升/下降/稳定)* @throttle: 是否需要抑制性能(温度超过触发点时设为true)** 返回值: 冷却设备的目标状态值(或THERMAL_NO_TARGET表示不激活)** 核心逻辑:* 1. 温度高于触发点时:* a. 趋势上升 → 提高冷却强度* b. 趋势下降 → 保持当前状态(避免频繁调整)* 2. 温度低于触发点时:* a. 趋势上升 → 保持当前状态* b. 趋势下降 → 降低冷却强度(若已达下限则关闭冷却)*/static unsigned long get_target_state(struct thermal_instance *instance,enum thermal_trend trend, bool throttle){struct thermal_cooling_device *cdev = instance->cdev;unsigned long cur_state; // 当前冷却状态unsigned long next_target; // 待计算的目标状态/* 获取冷却设备当前状态(如风扇转速档位) */cdev->ops->get_cur_state(cdev, &cur_state);next_target = instance->target; // 默认保持原状态dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);/* 处理未初始化的实例 */if (!instance->initialized) {if (throttle) {// 温度超标时:当前档位+1,并限制在有效范围内[lower,upper]next_target = clamp((cur_state + 1), instance->lower, instance->upper);} else {// 温度安全时:标记为不激活next_target = THERMAL_NO_TARGET;}return next_target;}/* 温度超过触发点时的处理 */if (throttle) {// 仅当温度持续上升时才提高冷却强度(避免震荡)if (trend == THERMAL_TREND_RAISING) {next_target = clamp((cur_state + 1), instance->lower, instance->upper);}}/* 温度低于触发点时的处理 */else {// 仅当温度持续下降时才降低冷却强度if (trend == THERMAL_TREND_DROPPING) {if (cur_state <= instance->lower) {// 已达最低档位则关闭冷却next_target = THERMAL_NO_TARGET;} else {// 否则降低一档next_target = clamp((cur_state - 1), instance->lower, instance->upper);}}}return next_target;}

target state的逻辑总结:如果当前温度高于trip温度,如果趋势是上升,选择更高的cooling 状态,如果趋势是下降,do nothing; 如果当前温度低于trip温度,如果趋势是上升,do nothing,如果趋势是下降,用更低的cooling状态,如果已经是最低的状态了,那么就deactive这个thermal instance
