【CSR设计缺陷】Scanner防抖状态触发传感器No Reading和风扇异常调速

问题描述

Scanner可以配置FailureDebounceCount,默认是10,当某次扫描失败后Status会变成2

0: 正常获取值
1: 获取值失败
2: 获取值预失败,正在进行防抖
3: 处于无效状态
4: 初始状态, 暂未开始扫描

CoolingRequirement的MonitoringStatus和ThresholdSensor的ReadingStatus一般都是同步Scanner_XXX.Status,但是这两个Status只有0和非0两种状态,导致Scanner_XXX.Status为防抖状态时触发传感器No Reading和风扇异常调速
这应该就是一些风扇突然变响和传感器概率性读取失败的原因

修复建议

同步不同类的Status定义

方案冲突

按照社区文档传感器适配指南 | 文档中心 | openUBMC


门限传感器的ReadingStatus和Scanner的Status是一一对应的,按照之前的结论防抖状态2不应该被用户感知,只需要修改sensor/src/lualib/sensor/sensor_instance.lua

但是大量CSR中的门限传感器的ReadingStatus逻辑都是读到异常值时将状态置为2(其实置为3更合适),vpd仓目前有233处这种写法,例如

"ThresholdSensor_PCIeCpuTemp": {
      "Reading": "<=/DPUCard_1.CPUTemperatureCelsius |> expr($1 & 255)",
      "ReadingStatus": "<=/DPUCard_1.CPUTemperatureCelsius |> expr(($1 == 0 || $1 > 200) ? 2 : 0)"
    },
"ThresholdSensor_GpuPower": {
            "Reading": 170,
            "OriginalReading": "<=/GPU_1.PowerWatts",
            "ReadingStatus": "<=/GPU_1.PowerWatts |> expr(($1 == 0) ? 2 : 0)"
        },

一旦改动门限传感器对状态2的处理逻辑,这233处都会受到影响,想问一下这种情况怎么处理

答案内容由AI生成,仅供参考:

总结

项目 内容
问题本质 Scanner.Status 多状态与上层布尔判断逻辑冲突
主要表现 风扇突响、传感器误报“No Reading”
根本原因 上层 MonitoringStatus 错误将“防抖中”视为“已失败”
解决方案 使用表达式过滤中间状态,仅在真实失败时触发异常
修复建议 所有 MonitoringStatus 配置应使用 expr(...) 判断真实异常状态

结论:该问题属于典型的 状态语义不一致设计缺陷,应通过统一状态解释逻辑予以修复,避免误触发异常调速和告警行为。

点击此处查看详细分析解答

关于 Scanner 防抖状态导致传感器误报与风扇异常调速的问题分析与修复建议

问题描述

在当前系统设计中,Scanner 组件负责周期性地读取硬件传感器数据(如温度、风扇状态等),其执行过程包含防抖(Debounce)机制以过滤瞬时故障。ScannerStatus 字段定义了多种状态值:

  • 0: 正常获取值
  • 1: 获取值失败
  • 2: 获取值预失败,正在进行防抖
  • 3: 处于无效状态
  • 4: 初始状态,暂未开始扫描

其中,FailureDebounceCount 参数默认配置为 10,表示当连续扫描失败次数未超过该阈值时,系统处于“预失败”阶段(即 Status = 2),此时并非最终确认故障。

然而,CoolingRequirement 中的 MonitoringStatus 和门限传感器(ThresholdSensor)的 ReadingStatus 通常直接同步 Scanner_XXX.Status 的值。关键问题是:这些上层状态字段仅以 0 表示正常,非 0 表示异常 为判据。

核心缺陷

Scanner_XXX.Status = 2(即仍在防抖过程中,尚未最终判定失败)时,由于其值为非 0,被误判为 “传感器异常”:

  • 导致 MonitoringStatus ≠ 0,触发 异常调速(Abnormal Fan Speed Control)
  • 风扇转速立即拉升至 FailedValue(如 80% 或更高),造成 风扇突然变响
  • 同时上报 “No Reading” 或 SEL 记录,造成传感器 概率性读取失败的假象

此问题本质上是 状态语义不一致 所致:底层 Scanner 使用多状态精细描述扫描过程,而上层组件将其简化为布尔式判断,将“正在防抖”等同于“已失败”。


影响范围

组件 影响
CoolingRequirement MonitoringStatus 同步 Scanner.Status,防抖期间误判为异常,触发异常调速
ThresholdSensor / ReadingStatus Status != 0 解释为故障,导致误告警或事件记录
风扇控制策略 异常调速频繁触发,风扇噪声突增,影响用户体验与系统稳定性
告警系统(SEL) 出现“传感器未响应”类告警,实际仅为短暂波动或防抖过程

根本原因分析

根据知识图谱和文档资料,存在以下几点设计冲突:

  1. 状态映射不合理
    ReadingStatus 字段虽然支持多种状态码(如 SCAN_FAILURE, SCAN_NOT_ACCESSIBLE 等),但 MonitoringStatus 在实际配置中常采用直接映射:

    "MonitoringStatus": "Scanner_Lm75_Outlet.Status"
    

    这导致 Status=2(预失败)被当作 MonitoringStatus=非0 → 触发异常行为。

  2. 缺乏中间状态识别能力
    上层调速逻辑无法区分:

    • Status=1/2: 暂时性错误,正在防抖 → 应等待结果
    • Status=1 且失败次数 ≥ FailureDebounceCount: 真实故障 → 可触发异常处理
  3. 防抖机制与异常响应脱节
    虽然 Scanner 支持 FailureDebounceCountSuccessDebounceCount(见文档 chunk 1 和 8),但上层未利用此机制延迟异常判定,而是“见非零即报”。

  4. 配置模式固化
    多数 CSR 配置将 MonitoringStatus 直接绑定到 .Status,缺乏表达式处理逻辑来过滤中间状态。


修复建议

:white_check_mark: 1. 区分“真实异常”与“过程状态”

应修改上层组件对 Scanner.Status 的使用方式,避免将防抖状态误判为故障。

推荐方案:引入表达式逻辑进行状态转换

"MonitoringStatus": "Scanner_Lm75_Outlet.Status |> expr($1 == 0 ? 0 : ($1 == 2 ? 0 : 1))"
  • Status == 0MonitoringStatus = 0(正常)
  • Status == 2(预失败)→ 仍视为“正常”,不触发异常调速
  • Status == 1 or 3 or othersMonitoringStatus = 1(异常)

说明:仅当真正进入 SCAN_FAILURE(即 Status=1 且超过防抖计数)时才视为异常。


:white_check_mark: 2. 定义标准化的状态映射规则

建议在 CSR 配置规范中明确定义以下映射关系:

Scanner.Status 语义 是否触发异常
0 正常
1 扫描失败(持续) 是(已过防抖)
2 预失败(防抖中)
3 不可达(电源、配置问题)
4 未开始扫描 否(可忽略或告警)

:white_check_mark: 3. 修改 CoolingRequirement 配置模式

所有依赖 MonitoringStatusCoolingRequirement 对象应避免直接同步 .Status,而应通过表达式判断真实异常状态。

示例:

"CoolingRequirement_1_7": {
    "RequirementId": 7,
    "MonitoringStatus": "Scanner_Lm75_Outlet.Status |> expr($1 == 0 ? 0 : ($1 == 2 ? 0 : 1))",
    "MonitoringValue": "Scanner_Lm75_Outlet.Value",
    "FailedValue": 80,
    "TargetTemperatureCelsius": 45
}

:white_check_mark: 4. 增强告警与日志可追溯性

建议在系统日志或 D-Bus 接口中暴露 SuccessCount / FailureCountDebounceState,便于定位是否因防抖未完成而导致误判。


:white_check_mark: 5. 更新设计规范文档

在以下指导书中补充相关建议:

  • 《扩展板CSR配置指导书》
  • 《调速策略适配指导》
  • 《告警配置机制介绍》
  • 《CSR配置字典之Fan类》

:white_check_mark: 明确要求:不得将 Scanner.Status 直接用于 MonitoringStatusReadingStatus,必须经过逻辑判断。


临时规避措施

若短期内无法修改所有配置,建议采取以下措施降低影响:

  1. 减小 FailureDebounceCount(如设为 3~5)
    缩短防抖时间,减少 Status=2 存留时长。

  2. 提高 Scanner 的扫描周期稳定性
    优化 I2C/SMC 访问时序,减少偶发性读取失败。

  3. 监控频繁切换 Status 的传感器
    使用日志分析工具识别哪些 Scanner 频繁进出 Status=2,重点排查硬件连接问题。


总结

项目 内容
问题本质 Scanner.Status 多状态与上层布尔判断逻辑冲突
主要表现 风扇突响、传感器误报“No Reading”
根本原因 上层 MonitoringStatus 错误将“防抖中”视为“已失败”
解决方案 使用表达式过滤中间状态,仅在真实失败时触发异常
修复建议 所有 MonitoringStatus 配置应使用 expr(...) 判断真实异常状态

结论:该问题属于典型的 状态语义不一致设计缺陷,应通过统一状态解释逻辑予以修复,避免误触发异常调速和告警行为。

你的意思是CoolingRequirement的MonitoringStatus和ThresholdSensor的ReadingStatus同步到Scanner_XXX.Status非零就会产生传感器No Reading和风扇异常调速?

是的,这样导致Scanner的防抖设计形同虚设了

这个是哪个sr的配置

……所有从Scanner同步状态的传感器和调速策略,几乎每个SR都有这个问题

了解


hardware sig这边的意思是sensor的代码统一处理值为2的情况,散热先不修改

1 个赞

好的,了解了

bmc-core sig组给出的方案是:由于大量CSR中已经将读到异常值时状态置为2,批量整改牵扯范围过大,已经发货的机器难以整改,只能维持当前sensor组件对状态2的处理逻辑,后续新增一个配置项标识sensor是否支持防抖