散热组件问题定位指南
本文档梳理风扇调速链路的关键逻辑与日志,用于现场快速定位"风扇转速异常 / 满转 / 不调速 / 识别失败 / 告警"等问题。
目录:本文已按二级/三级标题组织。上传到论坛后,在发帖编辑器选中正文点工具栏的「目录(TOC)」按钮(或用
[wrap=toc]…[/wrap]包裹),论坛会在右侧自动生成可跳转的浮动目录。
0. 调速整体链路(先看全貌)
温度传感器 → data_keeping(采集) → CustomPidUpdateSensorValue(喂温度给PID)
↓
libpid(C库) PID计算 + 环温曲线计算
↓
cooling_mgmt:get_pid_pwm() ← CustomReadInfo() 读回PID结果
↓
max(目标调速PWM, 环温PWM) → 异常策略覆盖(满转/告警转速)
↓
fan_service:set_fan_pwm → 适配层 Fan:set_pwm → I2C 下发到风扇MCU
核心要点:
- 真正的 PID 调速计算在 C 库
libpid内,Lua 侧只负责"喂温度 / 读结果 / 下发"。 cooling_control.log(PID 调速日志)由libpid输出,字段含义见第 2 节。- Lua 侧的散热运行日志写到
/var/log/Thermal.log,由cooling_utils.thermal_log()产生。 - 调速主循环在 cooling_mgmt.lua:每 1s 扫描策略/异常,每 2s 读 PID 结果并下发。
1. 风扇类型识别逻辑
代码:src/lualib/fan_object.lua(核心),配合 fan_type_object.lua、device_mgmt/fan_type_dev_mgmt.lua。
1.1 识别原理:基于"识别转速 + 单双转子"的特征匹配
识别本质是在固定 PWM 下测量实际转速,落到哪个机型的转速区间就是哪个机型。流程(函数 fan_identify):
- 建候选池:按风扇位置取所有可能机型
model_pool(fetch_by_position)。 - 测速过滤(函数
filter_type_by_speed):- 把 PWM 设到机型配置的
IdentifySpeedLevel,等 15s 稳定; - 采 5 次转速,去掉最大/最小取均值;
- 用均值与每个机型的
IdentifyRangeLow/IdentifyRangeHigh比较,过滤候选。
- 把 PWM 设到机型配置的
- 转子类型过滤(函数
filter_type_by_twins):通过FrontSpeed ~= 0判断是否双转子,与机型IsTwins匹配。 - 唯一性判断(
fan_identify收尾处):- 剩 1 个候选 → 识别成功;
- 剩多个 → 最多重试 5 次(每次等 10s);
- 剩 0 个 / 重试耗尽 → 识别失败。
1.2 识别状态与机型来源枚举
-- 识别状态(identify_status)
identify_status = { UNIDENTIFIED=0, IDENTIFYING=1, IDENTIFIED=2, IDENTIFY_FAILED=3 }
-- 风扇状态位(fan_status,按位)
fan_status = {
STATUS_NORMAL=0, STATUS_ERROR=1(0x1 转速偏差),
STATUS_TYPE_MISMATCH=2(0x2 5次识别失败),
STATUS_TYPE_MISMATCH_PCIE=4(0x4),
STATUS_MULTI_TYPE=8(0x8 混插告警),
STATUS_ACCESS_FAILED=16(0x10 MCU访问失败),
STATUS_STOP_ROTATION=32(0x20 转子停转)
}
-- 机型来源(model_source)
model_source = { NONE=0, PERSISTENT=1(数据库恢复), DEFAULT_MODEL=2(兜底), IDENTIFY=3(识别得到) }
1.3 识别失败如何处理 / 记录日志
- 失败 5 次 → 置
STATUS_TYPE_MISMATCH,ERROR 日志:
identify fan%d model failed. identify_cnt=%d. record_pwm=[...], record_speed=[...] - 识别过程中下电 → 置
IDENTIFY_FAILED,ERROR:detect power off when fan identifying - 设 PWM 失败 → ERROR:
Set the pwm of %s failed,直接返回
定位识别问题时,重点看
record_speed是否落在目标机型的IdentifyRange区间内。
1.4 识别结果持久化
识别成功后写入 db.FanInfo(SystemId/FanId/FanPosition/Model/IsTwins/FrontMaxSpeed/RearMaxSpeed 等)。BMC重启后优先从 DB 恢复(model_source=PERSISTENT),不再重新识别。
定位提示:若现场换了风扇但机型没变,可能是读了旧的持久化记录,需确认 DB 是否刷新。
1.5 识别未完成对调速的影响(重要)
PWMChannel.lua 的 configurable():
只要存在"在位且未识别"的风扇,整个 PWM 通道就不允许调速(返回 false)。
→ 这是"插了风扇但不调速"的常见根因之一:先查识别状态。
2. cooling_control.log 怎么读
cooling_control.log 是 PID 调速日志,由 C 库 libpid 计算并输出,记录每个调速设备每个周期的调速决策过程。Lua 侧通过 cooling_pid_intf 的 CustomReadInfo() 把结果读回(见 cooling_mgmt.lua 的 get_pid_pwm)。
2.1 字段含义对照表
| 字段 | 含义 |
|---|---|
DevID |
调速设备 Id |
Type |
调速设备类型,0 表示风扇,1 表示泵 |
ReqId |
目标调速策略 Id(RequirementId) |
T |
目标调速策略对应器件的温度 |
TarT |
目标调速策略的目标温度 |
TarPWM |
基于当前温度和目标温度通过 PID 计算出的转速(单位:PWM) |
EnvTNum |
环温曲线数量 |
EnvReqId |
环温曲线策略 id |
EnvT |
环境温度 |
EnvPWM |
基于环温的转速(单位:PWM) |
PIDPWM |
下发的转速 = max(环温转速 EnvPWM, 目标调速转速 TarPWM)(单位:PWM) |
MaxAllowTemp |
目标调速满转温度值(温度达到此值时该器件要求满转) |
TarSensorName |
目标调速策略关联传感器名称 |
EnvSensorName |
环温传感器名称 |
FrontSpeed |
前转子转速(单位:rpm) |
RearSpeed |
后转子转速(单位:rpm) |
重要约定:
ReqId全部显示为 255 → 当前没有任何目标调速策略生效(255/0xFF 为无效 ReqId)。- 环温调速依赖目标调速:环温调速要生效,前提是至少有一条目标调速策略生效。若只有环温调速而无任何目标调速生效,则环温调速也不生效。所以排查"环温不调速"时,先确认是否有目标调速在跑(即
ReqId不全是 255)。
2.2 读日志的标准思路(PWM → rpm 的因果链)
- 先看
PIDPWM:这是真正下发的占空比。它由max(TarPWM, EnvPWM)得出,所以"风扇转速高"无非两种来源——目标调速高,或环温调速高。 - 看
TarPWM来源:对比T(实测温度)和TarT(目标温度)。T > TarT→ PID 拉高TarPWM压温度;T越接近MaxAllowTemp,TarPWM越接近满转。- 用
TarSensorName+ReqId定位是哪个器件/策略在主导调速。
- 看
EnvPWM来源:环温EnvT越高,按环温曲线(EnvTNum段)算出的EnvPWM越高;EnvSensorName是环温传感器。- 若
PIDPWM == EnvPWM且EnvPWM > TarPWM,说明当前由环温曲线托底(与具体器件温度无关)。 - 前提:环温调速只有在"至少一条目标调速生效"时才生效。若
ReqId全是 255(无目标调速),即使配了环温曲线,环温调速也不会生效,此时风扇走兜底/初始转速而非环温值。
- 若
- 判断主导者:
PIDPWM等于谁,谁就是主导。PIDPWM == TarPWM→ 目标器件温度主导(看TarSensorName/T/TarT);PIDPWM == EnvPWM→ 环温主导(看EnvSensorName/EnvT)。
- 最后看实际转速
FrontSpeed/RearSpeed:核对下发 PWM 与实测 rpm 是否匹配。- PWM 高但 rpm 为 0/异常低 → 风扇硬件/堵转/线缆问题(转第 5 节告警)。
- 单转子机型
FrontSpeed通常为 0:FrontSpeed/RearSpeed是硬件 MCU 读回的设备树属性原值,Lua 侧不会把单转子的FrontSpeed改写成RearSpeed(exception_policy.lua、cooling_pid_intf.lua 都传原值)。所以单转子在本日志里FrontSpeed=0属正常,看转速以RearSpeed为准。 - 注意区分两个"前=后"的场景(不影响本日志的 FrontSpeed 字段):① 状态位
FrontStatus单转子时会被复制为RearStatus(fan_object.lua 的update_*_status逻辑);② IPMI 查询前转子转速get_fan_speed单转子时返回RearSpeed(fan_service.lua 的get_fan_speed)——这是查询返回值替换,不写回属性。
2.3 PWM ↔ 百分比 ↔ rpm 换算
- PWM 与百分比:
libpid内部转速单位是 PWM(0~255)。Lua 读回后换算为百分比:
target_pwm = fan_pwm / 2.55(见 cooling_mgmt.lua 的get_pid_pwm)。 - 下限保护:风扇计算转速 < 10% 时强制下发 10%(
get_pid_pwm内)。所以日志算出很低但实际不会低于 10%。 - 百分比 → 硬件值:适配层
Fan:set_pwm再换算回硬件占空比:
pwm_value = pwm_percent/100 * MaxSupportedPWM,四舍五入(Fan.lua 的set_pwm)。
转速比与占空比不一致属正常现象:下发占空比(PWM%)与实测转速比(实际 rpm / 满转 rpm)不完全相等是正常的,常见是转速比更低。
- 占空比越低,两者相差越大;0~10% 区间内的偏差都属正常,不必当故障排查。
- 这是风扇电机的固有特性(PWM 占空比与转速非严格线性),具体对应关系以风扇固件规格书为准。
- 真正需要关注的是 PWM 较高(如 >30%)却转速接近 0 的情况——那才是堵转/线缆/硬件问题(转第 5 节)。
2.4 另一个日志:/var/log/Thermal.log
Lua 侧运行日志写到 /var/log/Thermal.log,格式 [YYYY-MM-DD HH:MM:SS] <msg>,由 cooling_utils.lua 的 thermal_log 产生,每 5s 落盘一次。主要记录:
- 传感器健康/温度变化、进出风口温度、整机功率、风扇功率、风扇转速(threshold_sensor_data_keeping.lua);
- 调速策略 abnormal/normal 状态切换(exception_policy.lua)。
定位顺序建议:先
cooling_control.log看调速决策(为什么是这个 PWM),再Thermal.log看温度/状态上下文,最后看器件/告警日志看硬件。
3. 全风扇满转场景
满转 = 异常策略覆盖了正常 PID 调速结果。覆盖逻辑集中在 exception_policy.lua 与 abnormal_fan.lua。
异常转速以 key <异常类型:对象Id:级别> 存入 exp_speed_t,主循环每周期取异常表与 PID 结果取较大值下发。
满转/拉高触发条件一览
| # | 触发条件 | 代码位置 | 下发转速来源 |
|---|---|---|---|
| 1 | 温度点监控异常(传感器读取失败/超时,is_monitoring_abnormal) |
exception_policy.lua(监控异常分支) | CoolingRequirement 的 FailedValue(泵用 LiquidFailedValue) |
| 2 | 风扇不在位 NotInPosition(Front/RearPresence=0) | abnormal_fan.lua(get_fan_abn_status) |
AbnormalFan 策略 SpeedPercentage |
| 3 | 风扇停转 StopRotation(status bit5 = 0x20) | abnormal_fan.lua(get_fan_abn_status) |
同上 |
| 4 | 风扇转速异常 AbnormalRotation(status bit0 = 0x01) | abnormal_fan.lua(get_fan_abn_status) |
同上 |
| 5 | 风扇类型识别失败(未识别/混插,PWMChannel 不可调速) | PWMChannel.lua(configurable)/ fan_object.lua |
IdentifySpeedLevel/SpeedPercentage |
| 6 | exception_policy.lua(cooling_update_area_alarm_speed) |
各级 alarm speed |
关于第 6 项(温度告警阈值四级调速):该机制(
cooling_update_area_alarm_speed)在 openUBMC 中已废弃,不再使用。代码仍保留(exception_policy.lua 中cooling_update_area_alarm_speed相关调用),但生效前提是 CoolingRequirement 下发#ThresholdValue == 3的告警阈值与AlarmSpeed;openUBMC 不再包含此配置,因此实际不会触发。定位满转时无需考虑这一路径,聚焦第 1~5 项即可。
判定方法:满转时先查
cooling_control.log的PIDPWM是否 = 满转值;若 PID 算出的TarPWM/EnvPWM都不高却仍满转,说明是异常策略覆盖 → 转Thermal.log找 abnormal 记录,再到 abnormal_fan 的log:notice看具体故障类型(Presence/Status)。
故障恢复后,refresh_exp_speed_table会删除对应异常转速项,风扇回到正常 PID 调速(abnormal_fan.lua 的refresh_exp_speed_table)。
另一类满转:开机初始转速 InitLevelInStartup(PID 未接管)
除异常策略外,还有一种"非异常"的满转——风扇一直停留在开机初始转速 InitLevelInStartup:
- 触发条件:① 调速初始化失败(PID 未接管);② 初始化成功但没有任何目标调速生效(即
cooling_control.log中ReqId全为 255,见第 2 节)。两种情况下风扇都会一直保持InitLevelInStartup,默认值 100(满转)。 - 取值逻辑(cooling_init_service.lua 的初始转速取值):取配置的
InitLevelInStartup;若不在 [50,99] 区间则置为最大值(100)。即只有配置成 50~99 才算"被定制",否则兜底满转。 - 关键日志:
Bmc Reset Type(%s), init level(%s)(cooling_init_service.lua 的init_fan_speed)——init level就是实际下发的初始转速。软复位场景注释明确写到"pid接管失败将保持此转速"。 - 定位提示:满转且
cooling_control.log里ReqId全是 255 / 或日志根本没有有效 PID 输出 → 不是温度/故障触发,而是停在InitLevelInStartup。先看init level是多少,再回到第 2 节确认为何无目标调速生效、第 4 节确认初始化是否卡住。
4. 调速组件初始化逻辑
入口 main.lua → thermal_mgmt_app 的 init → cooling_service。
初始化时序
- 服务入口:
main.lua启动sd_bus、注册thermal_mgmt、thermal_mgmt_app.new()。 - cooling_service 构造(cooling_service.lua 构造函数):销毁旧单例确保干净状态,创建
cooling_init_service,等待两个同步标志:is_base_obj_added(配置+设备发现完成)cooling_init_service_is_end(开机初始转速下发完成)
- 对象基础设施(cooling_objs.lua):按序创建 fans / pumps / fans_config / pumps_config / policys / requirements / cooling_group / 异常策略等单例。
- 设备发现(thermal_mgmt_app.lua 资源发现回调):资源树按类名分发对象——
CoolingFan/CoolingPump/CoolingRequirement/CoolingPolicy/CoolingArea/CoolingConfig各自注册到对应实例;CoolingArea构建 fan/pump 分组。 - 发现完成判定(cooling_objs.lua 的发现完成判定):config 对象 + 所有 fan 对象 + 所有 FanId 就绪 →
is_base_obj_added=true。 - 开机初始转速(cooling_init_service.lua 的
init_fan_speed):按 BMC 复位类型(HARD_RESET / SOFT_RESET)决定何时下发初始转速set_fan_level,完成后置cooling_init_service_is_end=true。 - 主服务启动(cooling_service.lua 的
start):启动各 config、注册 PID 插件方法(plugin_method_init)、启动exp_policy / cooling_mgmt / cooling_ipmi / cooling_rpc、注册 IPMI 命令。 - 调速管理初始化(cooling_mgmt.lua 的
init):active_cooling_init初始化 PID(CustomTarTempCtrInit)、配置设备槽位、设置控制策略,最后start_cooling_job进入主循环。
常见初始化卡点
| 卡点 | 现象 | 日志线索 |
|---|---|---|
| 风扇 config / CoolingFan 对象未下发齐全 | is_base_obj_added 一直 false,PID 不启动,全程兜底转速(常满转) |
Check config obj fan config: ..., fan obj add complete: false(循环打印) |
| BMC 复位类型取不到 | 初始转速不下发,每 500ms 重试 | DEBUG: Skipping initialization |
| 设 PWM 失败 | 单风扇初始转速失败但不阻塞 | Set fan(id) pwm to level failed |
| PID 初始化异常 | PID 结果读不回,get_pid_pwm 直接 return |
PID buffer error, len=..., CMD=... |
定位提示:开机阶段"全满转"先排查是否卡在第 5/6 步——设备没发现齐 → PID 没起来 → 走兜底满转,而非真正的温度/故障触发。
5. 风扇告警逻辑
代码:abnormal_fan.lua(风扇),abnormal_pump.lua(液冷泵)。
5.1 告警条件与状态映射(get_fan_abn_status)
| 条件 | 判据 | 返回状态 | 级别 |
|---|---|---|---|
| 不在位 | FrontPresence / RearPresence = 0 | NotInPosition |
NOT_IN_PRESENT=1 |
| 停转 | Front/RearStatus & 0x20 (bit5) | StopRotation |
ABNORMAL_ROTATION=2 |
| 转速异常 | Front/RearStatus & 0x01 (bit0) | AbnormalRotation |
ABNORMAL_ROTATION=2 |
| 正常 | 以上都不满足 | Normal |
NORMAL=0 |
级别名映射见 cooling_enums.lua:Normal / Presence / Status。
5.2 告警处理流程(信号驱动 + 重试去抖)
- 订阅信号(
subscribe_*信号订阅):FAN_FRONT_PRESENCE / FAN_REAR_PRESENCE / FRONT_STATUS / REAR_STATUS变化触发process_fan_status_signal。 - 去抖重试(
process_fan_status_signal内的异步重试):状态变化时杀掉旧异步任务,新任务最多调get_fan_abn_status10 次、每次间隔 6s,确认稳定状态后才动作(避免瞬时抖动误告警)。 - 置位(断言):状态≠Normal → 取对应
AbnormalFan配置对象,生成异常转速项(key<AbnormalFan:FanId:Status>),把SpeedPercentage应用到该 FanGroup 全部风扇(set_*异常转速逻辑)。 - 复位(解除):状态=Normal →
refresh_exp_speed_table删除该风扇所有异常转速项,恢复正常调速。 - 日志:每次状态变化
log:notice(get_fan_abn_status各分支);异常转速增删在 exception_policy.lua 记录。
泵告警同构(abnormal_pump.lua 的
get_pump_abn_status):状态Normal / AbnormalRotation / NotInPosition / StopWorking。
6. 1U 风扇调速逻辑(适配层)
代码目录:include/device_tree/adapters/14100363_00000001050302044490/
板卡 ID 14100363_00000001050302044490 = 1U 服务器风扇板,默认 8 个双转子风扇(fan_max_num=8)。
6.1 1U 关键特性:相邻风扇 PWM 镜像(最易踩坑)
Fans.lua 的 get_fans_pwm(PWM 镜像处理):
for index = 1, self.fan_max_num, 2 do
-- 相邻风扇取第二个风扇转速
l_pwm[index] = l_pwm[index + 1]
end
奇数位风扇(1,3,5,7) 的 PWM 被强制改写成相邻偶数位(2,4,6,8) 的值,即风扇 PWM 由偶数位风扇统一控制(硬件特性要求):1 号风扇实际使用 2 号的 PWM、3 号使用 4 号的、5 号使用 6 号的、7 号使用 8 号的。
→ 定位提示:1U 上"奇数位风扇 PWM 下发与 PID 计算不一致"很可能不是 bug,是这条配对镜像逻辑——奇数位的 PID 计算值会被丢弃,真正生效的是对应偶数位的 PWM;看转速也以偶数位风扇为准。CoolingRequirement 监控同样用 RearSpeed(如 <=/Fan_5.RearSpeed)。
6.2 PWM 下发链路
- 百分比→硬件值:Fan.lua 的
set_pwm,pwm_value = pwm_percent/100*MaxSupportedPWM,四舍五入存HardwarePWM/ExpectedPWM。 - 批量下发:Fans.lua 的
set_fans_pwm把 8 个 PWM 打包为字节流,经PWMChip:Write(SetPWMCmd, ...)走 I2C 下发。
6.3 转速读取 / 在位 / 识别
- 转速:每风扇双转子
FrontSpeed / RearSpeed(rpm);get_fans_pwm经PWMChip:Read(0x18001100, fan_num)读回(Fans.lua 的get_fans_speed)。 - 在位:Fan.lua 的
get_present以RearPresence为准。 - 调速闸门:PWMChannel.lua 的
configurable—— 任一"在位且未识别"风扇会禁止整通道调速(见 1.5 节)。
6A. 多风扇板调速关键对象(FanId 不连续场景)
多风扇板机型下,每块风扇板各自从 1 开始编号本地风扇(persist_fan_id),系统启动时再按风扇板起始槽位重映射成全局唯一的 FanId/Slot。看日志时 FanId 不连续多半源于此,不是异常。
6A.1 两个关键对象/属性
| 对象/属性 | 含义 | 代码 |
|---|---|---|
FanBoardNum |
风扇板数量;挂在 PSR 的 CoolingConfig 上 |
fans_config.lua 的 get_fan_board_num;用于判定"所有风扇板对象是否都已分发完成" base.lua |
ThermalConfiguration.FanStartSlot |
每块风扇板的起始槽位号数组,按风扇板槽位索引 | thermal_configuration.lua |
6A.2 FanId 重映射规则
thermal_configuration.lua 的 alloc_slot:
fan_object.Slot = start_slot + fan_object.persist_fan_id - 1
fan_object.FanId = fan_object.Slot
即全局 FanId = 该板起始槽位 + 板内本地 id - 1。风扇板槽位由 Position(形如 CLU<n>)正则解析(match_fan_board_slot),起始槽位从 FanStartSlot[风扇板槽位] 取。
触发时机:风扇板对象与风扇对象都分发齐后,realloc_fan_slot → next_tick 异步执行 alloc_slot。已重分配过(FanId ~= persist_fan_id)则跳过,避免重复。
6A.3 示例(4 风扇板,每板 5,5,5,8 个风扇)
FanBoardNum : 4
FanStartSlot: [1, 6, 11, 31]
FanBoard1 起始槽位 1 → FanId 1~5
FanBoard2 起始槽位 6 → FanId 6~10
FanBoard3 起始槽位 11 → FanId 11~15
FanBoard4 起始槽位 31 → FanId 31~38
定位提示:
- cooling_control.log / Thermal.log 里
DevID/FanId跳号(如直接从 15 跳到 31)是FanStartSlot配置决定的,正常现象。- 多风扇板"部分板不调速 / 对象不全"先看
Receive cooling board ... cur num / cooling board num日志(base.lua 的风扇板接收回调):board_add_complete_num未达FanBoardNum说明有风扇板对象没分发齐,会阻塞update_cooling_device_obj_identify_result。- 启动时搜
set %s slot to %u(thermal_configuration.lua 的alloc_slot)和FanStartSlot: ...(get_fan_start_slot相关日志)可确认每块板的实际映射结果。
7. 快速定位 Checklist
按现象选入口:
A. 风扇满转/转速偏高
cooling_control.log看PIDPWM来源:=TarPWM(器件温度高,查TarSensorName/T/TarT)还是 =EnvPWM(环温高,查EnvSensorName/EnvT)。- 若 PID 值都不高却满转 → 异常策略覆盖:查
Thermal.logabnormal 记录 + abnormal_fanlog:notice(第 3、5 节)。 - 若
ReqId全是 255 / 无有效 PID 输出 → 停在开机初始转速InitLevelInStartup(默认 100):看Bmc Reset Type / init level日志(第 3 节末、第 2、4 节)。 - 排查识别/初始化未完成导致的兜底满转(第 1.5、4 节)。
B. 风扇不调速 / PWM 下发无效
- 查识别状态:有"在位未识别"风扇 → 整通道禁调速(第 1.5、6.3 节)。
- 1U 注意相邻镜像:奇数位被偶数位覆盖(第 6.1 节)。
- 查初始化是否卡在设备发现(第 4 节卡点表)。
C. 风扇类型识别失败
- 看
identify ... failed日志里的record_speed是否落在目标机型IdentifyRange内(第 1.3 节)。 - 确认单双转子 (
IsTwins/FrontSpeed) 是否与机型匹配(第 1.1 节)。 - 确认是否读了旧的 DB 持久化机型(第 1.4 节)。
D. 风扇告警
- abnormal_fan
log:notice看状态:Presence(不在位) / Status(停转或转速异常)(第 5 节)。 - 注意 10 次×6s 去抖窗口,瞬时抖动不会立即告警。
E. 实测转速与下发不符
- PWM 高但 rpm 为 0/低 → 硬件堵转/线缆(看
FrontSpeed/RearSpeed与状态位 bit0/bit5)。 - 单转子机型
FrontSpeed=0正常。
F. 温度持续升高达到满转温度也没有调速,风扇转速未升高,cooling_control.log未变化
关键日志:Send target tempconfig to pid, cmd: 122 0 0 1 120 0 7 7 60 50 0 4 1 1 2 2 3 3 4 4
这是下发的目标调速配置,查看环境上打印的最后一条此日志,前6位为header头,不关注
7 7 60 50 0 4 1 1 2 2 3 3 4 4解析
7 7 RequirementId属性,配置为U8的0xA则是A A,配置为0xAB则是 A B,B常见配置为槽位号
60:满转阈值
50:目标温度值
4表示风扇个数
1 1 2 2 3 3 4 4表示使用1 2 3 4风扇调速
如果日志中没有预期的调速配置,可能是
1:温度点未使能(见CoolingRequirement的IsValid属性逻辑),mdbctl设置日志界别为debug,Update requirement(id:0x%x) IsValid to %u, Invalid cause: %s
2:PowerState为OFF或者ONING但CoolingRequirement未配置ActiveInstandby
3:未配置对应的CoolingArea对象,Send target tempconfig to pid日志前会打印error日志Can not find cooling area for requirement(id:%u)
4:CoolingRequirement配置了Enabled属性,计算为false,此配置可能位于soft.sr,解析日志sr无法发现,需从环境上查看
G. 整机全风扇转速极高也无法散热
硬件相关定位方向
- 确认是否盖机盖。会造成风道紊乱,散热能力大幅散失
- 风扇装反。风道方向从 实验室->机箱 变成 实验室<-机箱
- 高功率卡、CPU等器件温度高,硬件排查
8. 关键文件索引
| 主题 | 文件 |
|---|---|
| 调速主循环 / 读PID结果 / 下发 | cooling_mgmt.lua |
| PID 接口(喂温度/环温曲线/控制模式) | cooling_pid_intf.lua |
| 异常/满转策略 | exception_policy.lua |
| 风扇告警 | abnormal_fan.lua |
| 泵告警 | abnormal_pump.lua |
| 风扇类型识别 | fan_object.lua / fan_type_object.lua |
| 初始化 | cooling_service.lua / cooling_init_service.lua / cooling_objs.lua |
| 多风扇板 FanId 重映射 | thermal_configuration.lua / fans_config.lua |
| 枚举定义 | cooling_enums.lua |
| 日志工具 / Thermal.log | cooling_utils.lua |
| 1U 风扇适配层 | Fan.lua / Fans.lua / PWMChannel.lua |
注:
cooling_control.log的字段由 C 库libpid输出,Lua 源码中不含这些字段名;其值经CustomReadInfo()读回到 cooling_mgmt.lua 的get_pid_pwm。本文只标注函数名与关键日志,定位时以实际代码为准。
9. 相关文档
①调速问题FAQ
[调速问题 | 文档中心 | openUBMC]
②调速策略适配指导
[调速策略适配指导 | 文档中心 | openUBMC]
③ 调速策略配置分享与调试技巧
[调速策略配置分享与调试技巧]
④风扇/风扇板适配指南
[风扇/风扇板适配指南 | 文档中心 | openUBMC]