问题描述
2280 V2 BS 双SP686C RAID环境,长时间AC掉电自动化出现PCIe RAID6Temp传感器获取信息异常,概率1/38
环境上有俩张raid卡 raid0能够正常获取信息,raid1获取信息失败
分析结论
MCTP通信失败
app.log中
framework.log中
2280 V2 BS 双SP686C RAID环境,长时间AC掉电自动化出现PCIe RAID6Temp传感器获取信息异常,概率1/38
环境上有俩张raid卡 raid0能够正常获取信息,raid1获取信息失败
MCTP通信失败
app.log中
framework.log中
答案内容由AI生成,仅供参考:
根据Context中提供的已解决问题的措施,此问题可以通过以下方向解决:
该问题本质上是一个典型的嵌入式系统启动时序争抢(Race Condition) 问题。它并非由硬件损坏或复杂的MCTP协议故障直接导致,而是由于AC自动化脚本中的复位周期过短与RAID卡管理代码中的不合理依赖逻辑共同作用,使得第二张RAID卡在系统反复重启期间始终无法完成初始化,最终表现为信息获取失败。通过简化和优化代码逻辑,并调整测试间隔,可以有效解决此问题。
好的,根据您提供的Context,我将为您综合分析“双SP686C RAID环境长时间AC掉电出现PCIe RAID6Temp传感器获取信息异常”的问题。
根据您的描述和Context中的信息,该问题的核心现象可以总结如下:
综合Context中的“实体”、“关系”及“文档块”信息,该问题并非单一的MCTP通信硬件故障,而是由软件逻辑与测试流程的不当设计引发的启动时序争抢问题。具体原因如下:
根据文档块1的分析,问题源于伙伴(客户)的代码逻辑:
lsobj PCIeCard等命令执行失败,间接加剧了启动时序问题的风险。根据Context中提供的已解决问题的措施,此问题可以通过以下方向解决:
该问题本质上是一个典型的嵌入式系统启动时序争抢(Race Condition) 问题。它并非由硬件损坏或复杂的MCTP协议故障直接导致,而是由于AC自动化脚本中的复位周期过短与RAID卡管理代码中的不合理依赖逻辑共同作用,使得第二张RAID卡在系统反复重启期间始终无法完成初始化,最终表现为信息获取失败。通过简化和优化代码逻辑,并调整测试间隔,可以有效解决此问题。
需要更多日志分析,还有你们的代码修改
日志已经通过邮件传递过给zhanglei
AC掉电重启10分钟后是否能获取到raid1信息
问题出现后,一直不会消失;
BMC重启才会恢复
用这个PR 验证下基本功能 还有你们的异常场景 看下能否解决
双1880(PCIe)RAID卡环境,BMC复位场景概率出现 get mctp endpoint failedinstall_mctp_writeread_cb_1 报错,极端情况下触发 attempt to call a nil value。
lua_State 竞态架构背景:
worker.new(1) 创建独立OS线程,拥有自己的 lua_State(L_worker),加载 sml_callbacks.lualua_State(L_smld),加载 cmds.luaref_value 机制:构造时 luaL_ref(L) + 捕获 m_L = main_thread(L),执行时 lua_rawgeti(m_L) + lua_pcall(m_L)竞态链路:
| 操作 | 线程 | lua_State | 说明 |
|---|---|---|---|
install_mctp_writeread_cb → set_mctp_writeread_cb → luaL_ref |
worker | L_worker |
回调注册时,ref_value构造函数在worker线程操作 L_worker 的registry |
SML命令执行 → mctp_writeread_cb → lua_pcall |
smld | m_L = main_thread(L_worker) = L_worker |
回调执行时,lua_function::operator() 在smld线程操作同一个 L_worker |
两个RAID卡并发场景:
set_mctp_writeread_cb 在worker线程执行 luaL_ref,修改 L_worker 的registry栈mctp_writeread 在smld线程执行 lua_pcall(L_worker),读取 L_worker 的栈lua_State,导致栈/registry损坏两种错误表现:
get mctp endpoint failedinstall_mctp_writeread_cb_1:lua_pcall 栈损坏,返回值错乱attempt to call a nil value:luaL_ref/luaL_unref 并发导致registry条目被释放,lua_rawgeti 返回nil核心思路:将 mctp_writeread 回调的注册和执行统一到 smld 线程,使 luaL_ref 和 lua_pcall 在同一个 lua_State(L_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_cb2. [init.lua](file:///home/workspace/storage/src/lualib/sml/init.lua) — 调用方
timeout_call 中改为 skynet.call('.smld', 'lua', 'set_mctp_writeread_cb', ctrl_idx)worker.new、__gc、start_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 跟踪
你能把验证报告发我吗