专门制作网站,注册城乡规划师报名,网站推广有哪些公司可以做,百度指数查询官网大数据原文#xff1a;蜗窝科技linux thermal framework(4)_thermal governor
1. 介绍
thermal governor是通过一定算法控制cooling device状态来控温的在这篇文章中#xff0c;我们使用一个简单的step_wise governor来说明整个过程。
2. thermal governor相关的API以及功能分析…原文蜗窝科技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 { //1name, 每个governor会有一个名字在温控的governors中常见的有power_allocator/userspace/step_wise char name[THERMAL_NAME_LENGTH]; //2bind_to_tz, governor绑定thermal_zone的回调函数 int (*bind_to_tz)(struct thermal_zone_device *tz); //3unbind_from_tzgovernor和thermal_zone解绑的回调函数 void (*unbind_from_tz)(struct thermal_zone_device *tz); int (*throttle)(struct thermal_zone_device *tz, int trip); //4)governor_listthermal 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来说主要的回调函数就是managemanage会在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在做好更新后重新遍历tripthermal_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); }} 1trend get_tz_trend首先得到温度趋势上升THERMAL_TREND_RAISING or 下降THERMAL_TREND_DROPPING
2throttle是否达到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