双SP686C RAID环境长时间AC掉电出现PCIe RAID6Temp传感器获取信息异常

问题描述

2280 V2 BS 双SP686C RAID环境,长时间AC掉电自动化出现PCIe RAID6Temp传感器获取信息异常,概率1/38

环境上有俩张raid卡 raid0能够正常获取信息,raid1获取信息失败

分析结论

MCTP通信失败

app.log中

framework.log中

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

解决方案与经验教训

根据Context中提供的已解决问题的措施,此问题可以通过以下方向解决:

  1. 修改代码逻辑: 删除伙伴代码中“等待第一张RAID卡ready后再启动第二张卡”的循环逻辑。两张RAID卡应具备独立的初始化流程,互不阻塞。
  2. 优化测试流程: 将AC上电复位周期延长至10分钟以上,确保第一张RAID卡有足够时间完成启动,从而使系统进入稳定运行状态后再执行后续操作。
  3. 代码审查: 由平台方(如华为)协助伙伴进行代码审查,排查并修复类似的循环等待和不合理的时序依赖。

总结

该问题本质上是一个典型的嵌入式系统启动时序争抢(Race Condition) 问题。它并非由硬件损坏或复杂的MCTP协议故障直接导致,而是由于AC自动化脚本中的复位周期过短与RAID卡管理代码中的不合理依赖逻辑共同作用,使得第二张RAID卡在系统反复重启期间始终无法完成初始化,最终表现为信息获取失败。通过简化和优化代码逻辑,并调整测试间隔,可以有效解决此问题。

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

好的,根据您提供的Context,我将为您综合分析“双SP686C RAID环境长时间AC掉电出现PCIe RAID6Temp传感器获取信息异常”的问题。

问题现象复盘

根据您的描述和Context中的信息,该问题的核心现象可以总结如下:

  1. 环境: 在搭载了双SP686C系列RAID卡的服务器上(如Kunlun 2280 V2 920BS)。
  2. 触发条件: 长时间执行AC掉电自动化测试。
  3. 故障表现:
    • 概率性发生: 在特定测试中,出现概率约为 1/38
    • 第二张RAID卡通信失败: 系统中,第一张RAID卡(RAID0)信息获取正常,但第二张RAID卡(RAID1)信息获取失败。
    • 传感器异常: 体现为“PCIe RAID6Temp”等传感器信息无法读取。
  4. 日志体现: 日志中记录了“Get BMC Mctp Info failed”和通信超时等MCTP相关报错。

根本原因分析

综合Context中的“实体”、“关系”及“文档块”信息,该问题并非单一的MCTP通信硬件故障,而是由软件逻辑与测试流程的不当设计引发的启动时序争抢问题。具体原因如下:

1. 核心问题:代码逻辑导致的启动阻塞

根据文档块1的分析,问题源于伙伴(客户)的代码逻辑:

  • 循环等待机制: 代码设计了一个循环,强制要求第二张RAID卡的任务必须等待第一张卡完全“Ready”后才能启动
  • 复位周期不合理: 在AC自动化测试中,系统上下电的复位周期(时间间隔)过短,仅有3分半钟左右。
  • 连锁反应: 由于复位周期过短,第一张RAID卡还没完成完整的初始化流程,系统就开始下一次复位。导致第一张卡始终无法真正“Ready”,从而第二张卡的任务被永久阻塞,始终无法启动或获取任何信息。

2. 间接关联:MCTP通信失败

  • MCTP(管理组件传输协议) 是用于BMC与RAID卡通信的关键协议(文档块9)。当RAID卡自身未能成功初始化时,基于MCTP的通信自然会失败。
  • 日志中记录的“Get BMC Mctp Info failed”和通信超时是RAID卡未完成初始化的结果,而非原因

3. 环境关联:AC自动化

  • AC自动化 作为测试流程,其自身的稳定性也是影响因素。文档块7和8中提到,在AC执行过程中,BMC内部子系统可能会出现异常重启,这也会导致lsobj PCIeCard等命令执行失败,间接加剧了启动时序问题的风险。
  • 文档块8中还确认,AC自动化本身会由于传感器读取逻辑问题(如数据类型转换导致高温告警)产生故障,表明AC环境的复杂性。

解决方案与经验教训

根据Context中提供的已解决问题的措施,此问题可以通过以下方向解决:

  1. 修改代码逻辑: 删除伙伴代码中“等待第一张RAID卡ready后再启动第二张卡”的循环逻辑。两张RAID卡应具备独立的初始化流程,互不阻塞。
  2. 优化测试流程: 将AC上电复位周期延长至10分钟以上,确保第一张RAID卡有足够时间完成启动,从而使系统进入稳定运行状态后再执行后续操作。
  3. 代码审查: 由平台方(如华为)协助伙伴进行代码审查,排查并修复类似的循环等待和不合理的时序依赖。

总结

该问题本质上是一个典型的嵌入式系统启动时序争抢(Race Condition) 问题。它并非由硬件损坏或复杂的MCTP协议故障直接导致,而是由于AC自动化脚本中的复位周期过短与RAID卡管理代码中的不合理依赖逻辑共同作用,使得第二张RAID卡在系统反复重启期间始终无法完成初始化,最终表现为信息获取失败。通过简化和优化代码逻辑,并调整测试间隔,可以有效解决此问题。

需要更多日志分析,还有你们的代码修改

日志已经通过邮件传递过给zhanglei

AC掉电重启10分钟后是否能获取到raid1信息

问题出现后,一直不会消失;

BMC重启才会恢复

用这个PR 验证下基本功能 还有你们的异常场景 看下能否解决

feat: test-storage-AtomGit

问题根因

现象

双1880(PCIe)RAID卡环境,BMC复位场景概率出现 get mctp endpoint failedinstall_mctp_writeread_cb_1 报错,极端情况下触发 attempt to call a nil value

根因:跨线程 lua_State 竞态

架构背景

  • worker线程worker.new(1) 创建独立OS线程,拥有自己的 lua_StateL_worker),加载 sml_callbacks.lua
  • smld线程:skynet服务线程,拥有自己的 lua_StateL_smld),加载 cmds.lua
  • ref_value 机制:构造时 luaL_ref(L) + 捕获 m_L = main_thread(L),执行时 lua_rawgeti(m_L) + lua_pcall(m_L)

竞态链路

操作 线程 lua_State 说明
install_mctp_writeread_cbset_mctp_writeread_cbluaL_ref worker L_worker 回调注册时,ref_value构造函数在worker线程操作 L_worker 的registry
SML命令执行 → mctp_writeread_cblua_pcall smld m_L = main_thread(L_worker) = L_worker 回调执行时,lua_function::operator() 在smld线程操作同一个 L_worker

两个RAID卡并发场景

  • RAID卡A的 set_mctp_writeread_cb 在worker线程执行 luaL_ref,修改 L_worker 的registry栈
  • RAID卡B的 mctp_writeread 在smld线程执行 lua_pcall(L_worker),读取 L_worker 的栈
  • 两个线程同时操作同一个 lua_State,导致栈/registry损坏

两种错误表现

  1. get mctp endpoint failedinstall_mctp_writeread_cb_1lua_pcall 栈损坏,返回值错乱
  2. attempt to call a nil valueluaL_ref/luaL_unref 并发导致registry条目被释放,lua_rawgeti 返回nil

修改方案

核心思路:将 mctp_writeread 回调的注册和执行统一到 smld 线程,使 luaL_reflua_pcall 在同一个 lua_StateL_smld)、同一个线程上执行。

修改内容

1. [cmds.lua](file:///home/workspace/storage/include/hwproxy/plugins/sml/cmds.lua) — smld线程

  • 迁入 do_mctp_writeread / mctp_writeread 函数
  • 新增 CMD.set_mctp_writeread_cb(ctrl_id),在smld线程调用 cbs:set_mctp_writeread_cb

2. [init.lua](file:///home/workspace/storage/src/lualib/sml/init.lua) — 调用方

  • timeout_call 中改为 skynet.call('.smld', 'lua', 'set_mctp_writeread_cb', ctrl_idx)
  • 移除worker线程基础设施(worker.new__gcstart_module

3. [sml_callbacks.lua](file:///home/workspace/storage/src/lualib/sml/sml_callbacks.lua) — worker线程

  • 移除 mctp_writeread 相关全部代码,保留worker骨架

修改后调用链

注册阶段:smld线程
  timeout_call → skynet.call('.smld', 'set_mctp_writeread_cb')
  → CMD.set_mctp_writeread_cb → cbs:set_mctp_writeread_cb
  → ref_value构造 → luaL_ref(L_smld)              ← smld线程操作L_smld

执行阶段:smld线程
  smld执行CMD命令 → SML库调用mctp_writeread_cb
  → lua_function::operator() → lua_pcall(m_L=L_smld) ← smld线程操作L_smld

两者都在 smld线程L_smld 上执行,彻底消除跨线程 lua_State 竞态。

使用修改后的代码跑AC 200次长时间后 问题没有复现
需要日志的话 麻烦给个邮箱

PR已经验证完成了 什么时候能够上库呢?

不好意思,很久没看社区了,200次AC没出现该问题, 基本带外管理功能验证了吗 ,多raid卡场景

验证了 web界面俩个raid卡的信息都能正常获取 温度也都能正常获取

我提个issue ,由issue: [缺陷] 双SP686C RAID卡MCTP通信失败:worker线程与smld线程跨lua_State竞态-storage-AtomGit 跟踪
你能把验证报告发我吗