散热组件问题定位指南

散热组件问题定位指南

本文档梳理风扇调速链路的关键逻辑与日志,用于现场快速定位"风扇转速异常 / 满转 / 不调速 / 识别失败 / 告警"等问题。

目录:本文已按二级/三级标题组织。上传到论坛后,在发帖编辑器选中正文点工具栏的「目录(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.luadevice_mgmt/fan_type_dev_mgmt.lua

1.1 识别原理:基于"识别转速 + 单双转子"的特征匹配

识别本质是在固定 PWM 下测量实际转速,落到哪个机型的转速区间就是哪个机型。流程(函数 fan_identify):

  1. 建候选池:按风扇位置取所有可能机型 model_poolfetch_by_position)。
  2. 测速过滤(函数 filter_type_by_speed):
    • 把 PWM 设到机型配置的 IdentifySpeedLevel,等 15s 稳定;
    • 采 5 次转速,去掉最大/最小取均值;
    • 用均值与每个机型的 IdentifyRangeLow / IdentifyRangeHigh 比较,过滤候选。
  3. 转子类型过滤(函数 filter_type_by_twins):通过 FrontSpeed ~= 0 判断是否双转子,与机型 IsTwins 匹配。
  4. 唯一性判断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.FanInfoSystemId/FanId/FanPosition/Model/IsTwins/FrontMaxSpeed/RearMaxSpeed 等)。BMC重启后优先从 DB 恢复(model_source=PERSISTENT),不再重新识别。
定位提示:若现场换了风扇但机型没变,可能是读了旧的持久化记录,需确认 DB 是否刷新。

1.5 识别未完成对调速的影响(重要)

PWMChannel.luaconfigurable()
只要存在"在位且未识别"的风扇,整个 PWM 通道就不允许调速(返回 false)。
→ 这是"插了风扇但不调速"的常见根因之一:先查识别状态。


2. cooling_control.log 怎么读

cooling_control.logPID 调速日志,由 C 库 libpid 计算并输出,记录每个调速设备每个周期的调速决策过程。Lua 侧通过 cooling_pid_intfCustomReadInfo() 把结果读回(见 cooling_mgmt.luaget_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 的因果链)

  1. 先看 PIDPWM:这是真正下发的占空比。它由 max(TarPWM, EnvPWM) 得出,所以"风扇转速高"无非两种来源——目标调速高,或环温调速高。
  2. TarPWM 来源:对比 T(实测温度)和 TarT(目标温度)。
    • T > TarT → PID 拉高 TarPWM 压温度;T 越接近 MaxAllowTempTarPWM 越接近满转。
    • TarSensorName + ReqId 定位是哪个器件/策略在主导调速。
  3. EnvPWM 来源:环温 EnvT 越高,按环温曲线(EnvTNum 段)算出的 EnvPWM 越高;EnvSensorName 是环温传感器。
    • PIDPWM == EnvPWMEnvPWM > TarPWM,说明当前由环温曲线托底(与具体器件温度无关)。
    • 前提:环温调速只有在"至少一条目标调速生效"时才生效。若 ReqId 全是 255(无目标调速),即使配了环温曲线,环温调速也不会生效,此时风扇走兜底/初始转速而非环温值。
  4. 判断主导者PIDPWM 等于谁,谁就是主导。
    • PIDPWM == TarPWM → 目标器件温度主导(看 TarSensorName/T/TarT);
    • PIDPWM == EnvPWM → 环温主导(看 EnvSensorName/EnvT)。
  5. 最后看实际转速 FrontSpeed/RearSpeed:核对下发 PWM 与实测 rpm 是否匹配。
    • PWM 高但 rpm 为 0/异常低 → 风扇硬件/堵转/线缆问题(转第 5 节告警)。
    • 单转子机型 FrontSpeed 通常为 0FrontSpeed/RearSpeed 是硬件 MCU 读回的设备树属性原值,Lua 侧不会把单转子的 FrontSpeed 改写成 RearSpeedexception_policy.luacooling_pid_intf.lua 都传原值)。所以单转子在本日志里 FrontSpeed=0 属正常,看转速以 RearSpeed 为准。
    • 注意区分两个"前=后"的场景(不影响本日志的 FrontSpeed 字段):① 状态位 FrontStatus 单转子时会被复制为 RearStatusfan_object.luaupdate_*_status 逻辑);② IPMI 查询前转子转速 get_fan_speed 单转子时返回 RearSpeedfan_service.luaget_fan_speed)——这是查询返回值替换,不写回属性。

2.3 PWM ↔ 百分比 ↔ rpm 换算

  • PWM 与百分比libpid 内部转速单位是 PWM(0~255)。Lua 读回后换算为百分比:
    target_pwm = fan_pwm / 2.55(见 cooling_mgmt.luaget_pid_pwm)。
  • 下限保护:风扇计算转速 < 10% 时强制下发 10%(get_pid_pwm 内)。所以日志算出很低但实际不会低于 10%。
  • 百分比 → 硬件值:适配层 Fan:set_pwm 再换算回硬件占空比:
    pwm_value = pwm_percent/100 * MaxSupportedPWM,四舍五入(Fan.luaset_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.luathermal_log 产生,每 5s 落盘一次。主要记录:

定位顺序建议:cooling_control.log 看调速决策(为什么是这个 PWM),再 Thermal.log 看温度/状态上下文,最后看器件/告警日志看硬件。


3. 全风扇满转场景

满转 = 异常策略覆盖了正常 PID 调速结果。覆盖逻辑集中在 exception_policy.luaabnormal_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 温度超告警阈值(NORMAL/MINOR/MAJOR/CRITICAL 四级) [openUBMC 已废弃] 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.logPIDPWM 是否 = 满转值;若 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.logReqId 全为 255,见第 2 节)。两种情况下风扇都会一直保持 InitLevelInStartup默认值 100(满转)
  • 取值逻辑cooling_init_service.lua 的初始转速取值):取配置的 InitLevelInStartup若不在 [50,99] 区间则置为最大值(100)。即只有配置成 50~99 才算"被定制",否则兜底满转。
  • 关键日志Bmc Reset Type(%s), init level(%s)cooling_init_service.luainit_fan_speed)——init level 就是实际下发的初始转速。软复位场景注释明确写到"pid接管失败将保持此转速"。
  • 定位提示:满转且 cooling_control.logReqId 全是 255 / 或日志根本没有有效 PID 输出 → 不是温度/故障触发,而是停在 InitLevelInStartup。先看 init level 是多少,再回到第 2 节确认为何无目标调速生效、第 4 节确认初始化是否卡住。

4. 调速组件初始化逻辑

入口 main.luathermal_mgmt_appinitcooling_service

初始化时序

  1. 服务入口main.lua 启动 sd_bus、注册 thermal_mgmtthermal_mgmt_app.new()
  2. cooling_service 构造cooling_service.lua 构造函数):销毁旧单例确保干净状态,创建 cooling_init_service,等待两个同步标志:
    • is_base_obj_added(配置+设备发现完成)
    • cooling_init_service_is_end(开机初始转速下发完成)
  3. 对象基础设施cooling_objs.lua):按序创建 fans / pumps / fans_config / pumps_config / policys / requirements / cooling_group / 异常策略等单例。
  4. 设备发现thermal_mgmt_app.lua 资源发现回调):资源树按类名分发对象——CoolingFan/CoolingPump/CoolingRequirement/CoolingPolicy/CoolingArea/CoolingConfig 各自注册到对应实例;CoolingArea 构建 fan/pump 分组。
  5. 发现完成判定cooling_objs.lua 的发现完成判定):config 对象 + 所有 fan 对象 + 所有 FanId 就绪 → is_base_obj_added=true
  6. 开机初始转速cooling_init_service.luainit_fan_speed):按 BMC 复位类型(HARD_RESET / SOFT_RESET)决定何时下发初始转速 set_fan_level,完成后置 cooling_init_service_is_end=true
  7. 主服务启动cooling_service.luastart):启动各 config、注册 PID 插件方法(plugin_method_init)、启动 exp_policy / cooling_mgmt / cooling_ipmi / cooling_rpc、注册 IPMI 命令。
  8. 调速管理初始化cooling_mgmt.luainit):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.luaNormal / Presence / Status

5.2 告警处理流程(信号驱动 + 重试去抖)

  1. 订阅信号subscribe_* 信号订阅):FAN_FRONT_PRESENCE / FAN_REAR_PRESENCE / FRONT_STATUS / REAR_STATUS 变化触发 process_fan_status_signal
  2. 去抖重试process_fan_status_signal 内的异步重试):状态变化时杀掉旧异步任务,新任务最多调 get_fan_abn_status 10 次、每次间隔 6s,确认稳定状态后才动作(避免瞬时抖动误告警)。
  3. 置位(断言):状态≠Normal → 取对应 AbnormalFan 配置对象,生成异常转速项(key <AbnormalFan:FanId:Status>),把 SpeedPercentage 应用到该 FanGroup 全部风扇(set_* 异常转速逻辑)。
  4. 复位(解除):状态=Normal → refresh_exp_speed_table 删除该风扇所有异常转速项,恢复正常调速。
  5. 日志:每次状态变化 log:noticeget_fan_abn_status 各分支);异常转速增删在 exception_policy.lua 记录。

泵告警同构(abnormal_pump.luaget_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.luaget_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.luaset_pwmpwm_value = pwm_percent/100*MaxSupportedPWM,四舍五入存 HardwarePWM/ExpectedPWM
  • 批量下发:Fans.luaset_fans_pwm 把 8 个 PWM 打包为字节流,经 PWMChip:Write(SetPWMCmd, ...) 走 I2C 下发。

6.3 转速读取 / 在位 / 识别

  • 转速:每风扇双转子 FrontSpeed / RearSpeed(rpm);get_fans_pwmPWMChip:Read(0x18001100, fan_num) 读回(Fans.luaget_fans_speed)。
  • 在位:Fan.luaget_presentRearPresence 为准。
  • 调速闸门:PWMChannel.luaconfigurable —— 任一"在位且未识别"风扇会禁止整通道调速(见 1.5 节)。

6A. 多风扇板调速关键对象(FanId 不连续场景)

多风扇板机型下,每块风扇板各自从 1 开始编号本地风扇(persist_fan_id),系统启动时再按风扇板起始槽位重映射成全局唯一的 FanId/Slot。看日志时 FanId 不连续多半源于此,不是异常。

6A.1 两个关键对象/属性

对象/属性 含义 代码
FanBoardNum 风扇板数量;挂在 PSR 的 CoolingConfig fans_config.luaget_fan_board_num;用于判定"所有风扇板对象是否都已分发完成" base.lua
ThermalConfiguration.FanStartSlot 每块风扇板的起始槽位号数组,按风扇板槽位索引 thermal_configuration.lua

6A.2 FanId 重映射规则

thermal_configuration.luaalloc_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_slotnext_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. 风扇满转/转速偏高

  1. cooling_control.logPIDPWM 来源:= TarPWM(器件温度高,查 TarSensorName/T/TarT)还是 = EnvPWM(环温高,查 EnvSensorName/EnvT)。
  2. 若 PID 值都不高却满转 → 异常策略覆盖:查 Thermal.log abnormal 记录 + abnormal_fan log:notice(第 3、5 节)。
  3. ReqId 全是 255 / 无有效 PID 输出 → 停在开机初始转速 InitLevelInStartup(默认 100):看 Bmc Reset Type / init level 日志(第 3 节末、第 2、4 节)。
  4. 排查识别/初始化未完成导致的兜底满转(第 1.5、4 节)。

B. 风扇不调速 / PWM 下发无效

  1. 查识别状态:有"在位未识别"风扇 → 整通道禁调速(第 1.5、6.3 节)。
  2. 1U 注意相邻镜像:奇数位被偶数位覆盖(第 6.1 节)。
  3. 查初始化是否卡在设备发现(第 4 节卡点表)。

C. 风扇类型识别失败

  1. identify ... failed 日志里的 record_speed 是否落在目标机型 IdentifyRange 内(第 1.3 节)。
  2. 确认单双转子 (IsTwins/FrontSpeed) 是否与机型匹配(第 1.1 节)。
  3. 确认是否读了旧的 DB 持久化机型(第 1.4 节)。

D. 风扇告警

  1. abnormal_fan log:notice 看状态:Presence(不在位) / Status(停转或转速异常)(第 5 节)。
  2. 注意 10 次×6s 去抖窗口,瞬时抖动不会立即告警。

E. 实测转速与下发不符

  1. PWM 高但 rpm 为 0/低 → 硬件堵转/线缆(看 FrontSpeed/RearSpeed 与状态位 bit0/bit5)。
  2. 单转子机型 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. 整机全风扇转速极高也无法散热
硬件相关定位方向

  1. 确认是否盖机盖。会造成风道紊乱,散热能力大幅散失
  2. 风扇装反。风道方向从 实验室->机箱 变成 实验室<-机箱
  3. 高功率卡、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.luaget_pid_pwm。本文只标注函数名与关键日志,定位时以实际代码为准。

9. 相关文档

①调速问题FAQ
[调速问题 | 文档中心 | openUBMC]

②调速策略适配指导
[调速策略适配指导 | 文档中心 | openUBMC]

③ 调速策略配置分享与调试技巧
[调速策略配置分享与调试技巧]

④风扇/风扇板适配指南
[风扇/风扇板适配指南 | 文档中心 | openUBMC]

4 个赞