【问题现象】100次AC,出现两次无带宽信息,偶现
【问题现象分析】
日志中发信有相关打印
pcie_device ERROR: pcie_card.lua(115): link_speed_to_str:faild to link speed to string(0)
查看代码发现函数入参为0,但links_table中没有0
link_width_to_str的调用点是执行get_pcie_info_from_ipmi后将local link_width_ability = ((ret[1] >> PCIE_LINK_WIDTH_OFFSET) + (ret[2] << PCIE_LINK_WIDTH_OFFSET)) & PCIE_LINK_WIDTH_MASK
和 local link_width = ((ret[3] >> PCIE_LINK_WIDTH_OFFSET) + (ret[4] << PCIE_LINK_WIDTH_OFFSET)) & PCIE_LINK_WIDTH_MASK当作参数传入link_width_to_str中,
但是local function get_pcie_info_from_ipmi(bus, pcie_info)函数中log:info(‘get pci register info successfully’)在日志中并没有打印,也没有打印log:error(‘pcie_info is nil’),初步怀疑是命令执行失败,麻烦问下为啥会失败呢,感谢
答案内容由AI生成,仅供参考:
关于长时间AC后FC卡偶现无带宽信息的问题分析
问题现象
在进行100次AC(上电/下电)循环测试时,偶现两次FC卡无法获取带宽信息的情况。具体表现为:
- PCIe功能数据(
PCIEFunctionDate)中的关键带宽参数均为 "N/A"
- 相关字段包括
LinkSpeed、LinkSpeedAbility、LinkWidth、LinkWidthAbility、MaxPCIeType 等均缺失
JSON响应示例如下:
{
"AssociateResource": "CPU4",
"DeviceId": "0xf400",
"LinkSpeed": "N/A",
"LinkSpeedAbility": "N/A",
"LinkWidth": "N/A",
"LinkWidthAbility": "N/A",
"MaxPCIeType": "N/A",
"SubsystemId": "0xf401",
"SubsystemVendorId": "0x10df"
}
日志与代码层面的发现
错误日志
日志中出现以下关键错误信息:
pcie_device ERROR: pcie_card.lua(115): link_speed_to_str: faild to link speed to string(0)
代码逻辑分析
-
函数调用路径为:get_pcie_info_from_ipmi() → 提取寄存器值 → 传入 link_speed_to_str() 和 link_width_to_str()
-
参数计算方式:
link_width_ability = ((ret[1] >> PCIE_LINK_WIDTH_OFFSET) + (ret[2] << PCIE_LINK_WIDTH_OFFSET)) & PCIE_LINK_WIDTH_MASK
link_width = ((ret[3] >> PCIE_LINK_WIDTH_OFFSET) + (ret[4] << PCIE_LINK_WIDTH_OFFSET)) & PCIE_LINK_WIDTH_MASK
-
异常点:
link_speed_to_str() 被传入参数 0
- 但在转换表
links_table 中没有定义 0 的映射,导致转换失败
- 更重要的是:未在日志中看到
get pci register info successfully 成功提示,也未打印 pcie_info is nil 的错误信息
可能原因分析
根据知识库和问题现象,可能的原因如下:
1. IPMI命令执行失败或超时
get_pcie_info_from_ipmi 函数依赖IPMI接口获取PCIe设备的寄存器信息
- 在频繁AC场景下,BMC或IPMI服务可能尚未完全初始化完成,导致IPMI命令执行失败
- IPMI作为标准化硬件管理接口,在系统启动初期可能存在短暂不可用窗口期,尤其是在多次上下电后资源未正确释放或状态异常
2. 数据同步与时序问题
- PCIe链路协商需要一定时间,在系统刚上电时可能还未完成链路训练(Link Training)
- 此时查询PCIe设备状态,可能因物理链路尚未稳定而导致读取失败
- 尤其对于高速链路(如Gen4/Gen5),链路训练时间更长,更容易出现此类竞态条件
3. BMC固件数据获取逻辑缺陷
- 当前代码逻辑中:
- 成功日志仅在明确收到有效返回时打印
- 失败路径应打印
pcie_info is nil 错误
- 但两者均未出现,说明:
- IPMI命令可能未实际发出
- 或返回结果既不是成功也不是nil,而是中间状态(如空数组、无效数据包等)
- 存在边缘情况处理缺失
4. PCIe卡初始化不稳定
- 某些FC卡(特别是光纤通道卡)对供电稳定性、复位时序敏感
- 多次AC可能导致电源波动,影响PCIe卡的正常初始化
- 导致BIOS/UEFI无法正确枚举设备,进而无法通过IPMI上报正确信息
建议排查方向
日志增强建议
在 get_pcie_info_from_ipmi 函数中增加以下日志输出:
log:debug("Executing IPMI command for bus: %d", bus)
local ret = ipmi_command(...)
if not ret then
log:error("IPMI command returned nil or false")
elseif #ret == 0 then
log:warn("IPMI command returned empty response")
else
log:info("IPMI command succeeded with %d bytes", #ret)
end
增加重试与延时机制
for i = 1, 3 do
local ret = get_pcie_info_from_ipmi(bus, pcie_info)
if ret and isValid(ret) then
break
end
sys.sleep(100) -- 短暂延时后重试
end
测试建议
- 在AC后固定延迟一段时间(如3秒)再读取PCIe信息,观察是否改善
- 抓取BMC与主机之间的IPMI通信日志(RMCP+),确认命令是否发送成功
- 检查是否存在IPMI队列积压或超时丢包现象
结论
该问题是由于在频繁AC场景下,IPMI接口未能及时返回有效的PCIe链路信息所致,根本原因很可能是:
- 时序问题:系统启动过快,PCIe链路未完成协商
- IPMI服务不稳定:在BMC初始化过程中存在短暂不可用期
- 代码健壮性不足:对异常返回值处理不完善,缺少重试机制
建议结合日志增强、增加初始化等待时间、引入重试机制等手段进行优化。
相关链接:
- CX6网卡不显示连接速率规格、当前速率和最高协议
- OS下电后存在日志刷屏
- openUBMC 25.06 版本适配E810网卡,PCIe卡信息未显示
- 系统管理-其他-PCIE卡页面槽位号和CPU归属信息不同步
- IPMI管理定位问题 | 文档中心 | openUBMC
您好,info级别日志默认是不打印的,如果要打印info级别日志需要将环境的日志打印级别调整到info或者debug,如果已经调整打印级别就是ipmi数据没有发通。
从问题来看,有可能是读取到的imu信息相关位的数据不对,可能是收到的数据不对或者启动时pcie卡带宽数据还没有获取。后续定位建议在 get_pcie_info_from_impi函数中增加对payload的打印看具体回传,在parse_info_from_pmu调用后看看各个位的解析,确定是只有一个数据不对还是整体读取有问题。
问题已经确认了,根因是
1、板载网卡中bdfno 、DevBus、DevDevice 等值都为0,导致sync_pcie_addr_info 函数中for循环执行不下去,被拦截
2、上级调用会重复尝试 sync_pcie_addr_info 120 次;
3、每一次调用都会发送一次 sync_pai_to_device_complete 信号;
4、这个信号会导致创建一个新的 pcie_and_ocp_task 任务,并在这个任务中每分钟刷新一次 link width 和 link speed 相关信息;
5、所以,最终导致重复创建了 120 个 pcie_and_ocp_task 任务;
6、120 个 pcie_and_ocp_task 任务造成访问 IMU 太过频繁,发生阻塞,导致出现部分 link width 和 link speed 相关信息获取失败的情况