长时间AC,FC卡偶现无带宽信息

【问题现象】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"
  • 相关字段包括 LinkSpeedLinkSpeedAbilityLinkWidthLinkWidthAbilityMaxPCIeType 等均缺失

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)

代码逻辑分析

  1. 函数调用路径为:get_pcie_info_from_ipmi() → 提取寄存器值 → 传入 link_speed_to_str()link_width_to_str()

  2. 参数计算方式:

    • 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
  3. 异常点

    • 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上报正确信息

建议排查方向

:magnifying_glass_tilted_left: 日志增强建议

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

:gear: 增加重试与延时机制

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

:test_tube: 测试建议

  1. 在AC后固定延迟一段时间(如3秒)再读取PCIe信息,观察是否改善
  2. 抓取BMC与主机之间的IPMI通信日志(RMCP+),确认命令是否发送成功
  3. 检查是否存在IPMI队列积压或超时丢包现象

结论

该问题是由于在频繁AC场景下,IPMI接口未能及时返回有效的PCIe链路信息所致,根本原因很可能是:

  • 时序问题:系统启动过快,PCIe链路未完成协商
  • IPMI服务不稳定:在BMC初始化过程中存在短暂不可用期
  • 代码健壮性不足:对异常返回值处理不完善,缺少重试机制

建议结合日志增强、增加初始化等待时间、引入重试机制等手段进行优化。

相关链接:

  1. CX6网卡不显示连接速率规格、当前速率和最高协议
  2. OS下电后存在日志刷屏
  3. openUBMC 25.06 版本适配E810网卡,PCIe卡信息未显示
  4. 系统管理-其他-PCIE卡页面槽位号和CPU归属信息不同步
  5. 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 相关信息获取失败的情况