【求助】NC-SIoverMCTPoverSMBus超时(米尔3093开发板I2C-8)

问题描述

OpenUBMC通过MCTP over SMBus通信。MCTP Set EID命令通信正常。但是适配使用Hi182x的网卡NC-SI over MCTP,就出现“method call timeout”。

如下是在component_drivers的chip和bus层增加elog的现象:

1、增加log

在component_drivers的如下文件的函数中增加打印:

bus层:drivers/internal/bus/bus_i2c/i2c.cpp的bus_i2c::normal_read()增加打印。

chip层: drivers/internal/chip/chip_base/chip.cpp的chip_base::data_access()中增加打印。

2、 【正常】MCTP 控制报文交互正常,成功创建endpoint。

~ ~ $ busctl --user tree bmc.kepler.mctpd 中有

[2026-03-16 16:24:16] /bmc/kepler/Systems/1/Mctp
[2026-03-16 16:24:16] /bmc/kepler/Systems/1/Mctp/Endpoint
[2026-03-16 16:24:16] /bmc/kepler/Systems/1/Mctp/Endpoint/0103_50
[2026-03-16 16:24:16] /bmc/kepler/Systems/1/Mctp/Endpoint/0103_50/2
[2026-03-16 16:24:16] /bmc/kepler/Systems/1/Mctp/MctpBinding
[2026-03-16 16:24:16] /bmc/kepler/Systems/1/Mctp/Routing
[2026-03-16 16:24:16] /bmc/kepler/mctpd
[2026-03-16 16:24:16] /bmc/kepler/mctpd/MicroComponent
[2026-03-16 16:24:16] /bmc/kepler/mctpd/MicroComponent/Debug

3、【异常】使用Hi182x的网卡NC-SI驱动进行网卡管理,MCTPD报timeout超时:

3.1 修改component_drivers: drivers/pcie_nic_card/hisi/hi182x/hi182x_card.cpp中的hi182x_card::start_ncsi_protocol(),使得及时BDF是0,也创建mctp对象。

3.2 component_drivers: libraries/mctp/mctp.cpp中增加request日志。

最终app.log中的日志

a) NC-SI over MCTP发送Request

image

b) chip层写Request: (没有添加写Request的详细数据LOG)

image

c) chip和bus层读Response:bus层将网卡回应的数据全部读回了,chip层也从bus层全部拿到了Response。

d) 15秒后MCTP层报timeout:()

component_drivers主机libraries/mctp/mctp.cpp的mctp::request()函数中调用service->timeout_call()设置的超时是15秒

image

环境信息

  • 操作系统:Ubuntu 24.04

  • 软件版本:OpenUBMC2512,没有SP1。参考《南向适配网迅网卡经验分享》进行自己网卡的SMBus适配,使用的OpenUBMC master,网卡纯slave。MCTP over SMBus帧中“Command Code”是0x1F。

  • 硬件配置:米尔3093开发板,使用I2C-8,网卡csr中driver和mctp相关配置:

“Unit”: {
“Type”: “PCIeNicCard”,
“Name”: “PCIeNicCard_1”,
“Compatible”: [“hisi_1822”, “hisi_182x”]
},

“Chip_SmbusChip”: {
“Address”: 100,
“AddrWidth”: 1,
“OffsetWidth”: 1,
“WriteTmout”: 1000,
“ReadTmout”: 1000,
“HealthStatus”: 0,
“ReadRetryTimes”: 3,
“DrvWriteDelay”: 255,
“WriteInterval”:255,
“ReadInterval”:255
},

“MctpBinding_1”: {
“BmcSMBusEid”: 8,
“BmcSMBusPhyAddr”: 16
},

“Endpoint_1”: {
“TargetEid”: “${Slot} |> expr($1 + 8)”,
“TargetPhyAddr”: 50,
“MessageType”: 2,
“MediumType”: 128,
“RefChip”: “#/Chip_SmbusChip”
},

重现步骤

  1. 网卡先启动,准备好SMBus总线上应答MCTP控制报文Request、NC-SI over MCTP 标准/OEM命令

  2. 启动MYIR 3093开发板,直到启动完成,导出app.log分析

期望结果

NC-SI over MCTP的命令与MCTP控制报文一样能够及时送达MCTPD。

实际结果

貌似MCTPD及时收到了控制报文(Set EID)的Response,而NC-SI over MCTP的Response超时了。

尝试过的解决方案

1、怀疑I2C总线读到的数据长度(129个)超过了Response的实际程度、造成上层解析出问题。修改网卡侧的I2C读响应处理、在没有数据时就不回应,结果造成总线挂死。观察《南向适配网迅网卡经验分享》中的tracmctp的截图,其SMBus_OEM Capture [RECV]中也是读取了129字节。 推测这个长度应该不影响MCTPD的解析。

2、怀疑网卡SMBus响应读Response时没有回送MCTP over SMBus的“Command Code” 0x1F;但修改后MCTP的Set EID Response就过不去,创建Endpoint失败。

内容大小竟然有限制,补充1、3.1和3.2的修改截图:

bus层:drivers/internal/bus/bus_i2c/i2c.cpp的bus_i2c::normal_read()增加打印

chip层: drivers/internal/chip/chip_base/chip.cpp的chip_base::data_access()中增加打印。

~ ~ $ busctl --user tree bmc.kepler.mctpd 中有

3.1 修改component_drivers: drivers/pcie_nic_card/hisi/hi182x/hi182x_card.cpp中的hi182x_card::start_ncsi_protocol(),使得即使BDF是0,也创建mctp对象。

3.2 component_drivers: libraries/mctp/mctp.cpp中增加request日志。

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

总结与结论

项目 分析结论
MCTP 控制通路是否正常 :white_check_mark: 正常,Set EID 成功,Endpoint 已创建
NC-SI 请求是否发出 :white_check_mark: 是,mctp::request() 成功触发
I2C 层是否收到响应 :white_check_mark: 是,返回 129 字节数据
根本原因定位 :red_question_mark: 主要在 MCTP 协议层处理逻辑,可能为:
1. 消息类型(MessageType)不匹配
2. MediumType 配置错误(SMBus_OEM 未支持)
3. smbus_write_read_service 未触发回调
4. mctpd 忽略了响应包
非 I2C 硬件问题 :white_check_mark: 排除物理层故障
点击此处查看详细分析解答

NC-SI over MCTP over SMBus 超时问题分析与排查

问题概述

用户在使用 米尔3093开发板(搭载 OpenUBMC 2512 版本)进行 Hi182x 网卡适配时,通过 MCTP over SMBus 协议进行 NC-SI(NC-SI over MCTP)通信出现 method call timeout 异常,表现为:

  • :white_check_mark: MCTP 控制报文(如 Set Endpoint ID)通信正常,能够成功创建 MCTP Endpoint;
  • :cross_mark: NC-SI over MCTP 命令调用失败mctpd 报告“method call timeout”(15秒超时);
  • :white_check_mark: 下层 I2C/SMBus 层已正确读取到完整的 Response 数据(129字节),I2C_Driver 返回正常;
  • :cross_mark: 但上层 mctpd 组件未正确处理响应,最终导致业务层请求超时。

该问题表现出典型的 “底层通信成功、上层协议处理失败” 的特征。


系统架构与通信流程回顾

1. 协议栈结构

+----------------------------+
|    NC-SI over MCTP (业务)   |
+----------------------------+
|      MCTP 协议层 (MCTPD)     |
+----------------------------+
|     SMBus 传输层 (I2C)      |
+----------------------------+
|       Hi182x 网卡 (Slave)    |
  • MCTP Over SMBus 是一种将 MCTP 协议封装在 SMBus Write-Read 事务中传输的机制。
  • 通信基于 SMBus 的 Block Write - Block Read Process Call 模式:
    • 写操作:发送 MCTP 请求帧(含 Command Code 0x1F)
    • 读操作:从设备读取 MCTP 响应帧(含返回数据)

2. 关键组件职责

组件 职责
I2C_Driver 执行物理 I2C 读写,返回原始字节流
Chip_SmbusChip_0103_dev 代表 SMBus 从设备节点,与网卡通信
mctpd 管理 MCTP Endpoint、处理 MCTP 消息编解码、超时控制
create_mctp_endpoint_for_smbus 创建 MCTP over SMBus 的通信 Endpoint

故障现象分析

:white_check_mark: 成功场景:MCTP Set EID 命令

根据日志,MCTP Set Endpoint ID 命令流程成功执行:

  1. 主机发送 MCTP 控制命令
  2. Chip_Smbuschip_0103 成功返回 129 字节响应
  3. mctpd 成功解析并创建 Endpoint
  4. /bmc/kepler/Systems/1/Mctp/Endpoint/0103_50 路径可见

:backhand_index_pointing_right: 表明 MCTP over SMBus 的基础通信链路是通的

:cross_mark: 异常场景:NC-SI over MCTP 超时

尽管:

  • I2C 层返回成功(I2c read success, data length: 129
  • 数据内容完整可读(hex dump 可见 MCTP 响应头 1e 65 ...
  • mctp::request() 设置了 15s 超时

但最终 mctpd 仍抛出异常:

daemon ERROR: mctp.cpp(76): mctp::request exception, shm method call timeout

可能原因深度分析

:white_check_mark: 已排查或非根本原因

排查项 结论
I2C 数据长度是否异常(129字节) :cross_mark: 否。129字节是标准 SMBus Block Read 最大长度(1 byte len + 128 byte data),符合规范;且《南向适配网迅网卡经验分享》中也出现相同长度。
是否缺少 Command Code(0x1F) :cross_mark: 否。实验表明若网卡不返回该字段,连 Set EID 都无法通过,而当前 Set EID 已成功。
总线冲突或挂死 :cross_mark: 否。总线可正常处理 Set EID 和 NC-SI 请求,无永久性故障。

:warning: 潜在根本原因分析

1. mctpd 上层未正确“唤醒”或“回调”完成请求

  • 现象:I2C_Driver 已收到 Response,但 mctpd 仍超时。
  • 原因推测:
    • mctpd 发起请求后进入等待状态。
    • SMBus 中断或事件处理完成后,未触发正确的 Response 回调函数
    • 可能是:smbus_write_read_service.lua 或其底层驱动未将 Response 正确传递给 mctpd 消息循环。
  • 支持证据:
    {"entity1": "mctpd", "entity2": "smbus_write_read_service.lua", "description": "mctpd relied on smbus_write_read_service.lua for SMBUS operations, which reported an invalid byte count."}
    

:backhand_index_pointing_right: 存在 smbus_write_read_service.lua 处理异常的历史记录,可能导致 Response 被丢弃或错误处理。


2. SMBus 响应帧格式与 mctpd 解析器不兼容

虽然数据量为129字节,但其内容结构需严格符合 MCTP over SMBus + NC-SI 的封装规范。

查看 NC-SI 响应示例首字节:

1e 65 01 08 ...
  • 0x1E = 包头长度(Length)
  • 0x65 = MCTP_Message_Type = MCTP_MESSAGE_TYPE_NCSI (0x02),但此处值为 0x65
  • 问题:MCTP 消息类型字段异常

标准定义:

  • MCTP_MESSAGE_TYPE_NCSI = 0x02
  • 应在 MCTP Header 中明确指出

但实际抓包显示可能未正确设置此字段,或厂商私有编码未被 mctpd 正确识别。

:backhand_index_pointing_right:mctpd 仅监听类型为 0x02 的消息,而 Hi182x 返回了非标准类型,则响应会被忽略 → 导致“看不见响应”从而超时。


3. Endpoint 配置错误,medium_type 或 msg_type 不匹配

关键配置:

"Endpoint_1": {
  "TargetEid": "...",
  "TargetPhyAddr": 50,
  "MessageType": 2,           // 应为 MCTP_MESSAGE_TYPE_NCSI
  "MediumType": 128,          // 128 = SMBus_OEM?
  "RefChip": "#/Chip_SmbusChip"
}
  • MessageType=2 :check_mark: 正确(对应 NC-SI over MCTP)
  • MediumType=128 :red_question_mark: 值为 SMBus_OEM?需确认 OpenUBMC 是否支持

根据文档:MCTP 支持 PCIe(0x0F)SMBus(0x02)SMBus_OEM(0x80) [注意:0x80 是 128]

:red_exclamation_mark: 若 Hi182x 使用的是 SMBus_OEM (128) 协议模式,而 mctpd 的处理逻辑未启用或不兼容该模式,则无法解包。


4. 请求/响应事件未绑定同一 Transaction Context

  • mctpd 可能使用 Transaction IDSequence Number 匹配请求与响应。
  • 若响应中未携带有效 Sequence Number,或编码格式不一致(如大端/小端),可能导致无法关联响应。
  • 特别是 Hi182x 的实现若与 Mellanox / Broadcom 等主流网卡不符,容易出现兼容性问题。

5. 中断延迟导致 timeout_call 提前触发

  • 用户指出 timeout_call 设置为 15s,但日志显示实际在短时间内即超时。
  • 可能是:
    • timeout_call 参数传参错误导致实际超时极短;
    • 或 D-Bus 异步调用机制被阻塞,事件未能及时派发。

解决方案建议

:white_check_mark: 方案一:验证并修复 MCTP 消息类型字段

目标:确保网卡返回的 MCTP 响应中 Message Type 字段为标准 0x02(NC-SI)。

操作步骤

  1. 使用 tracemctp 工具捕获 MCTP over SMBus 流量:
    tracemctp start
    # 执行 NC-SI 命令
    tracemctp stop
    
  2. 查看 Response 是否携带有效的 MCTP Header,尤其是:
    • Byte offset 2: IC / TO (usually 0x01)
    • Byte offset 3: Packet SNA / Header Reserved
    • Byte offset 4: Message Type → 必须为 0x02
  3. 若非 0x02,请调整网卡固件或驱动将其设为标准类型。

:white_check_mark: 方案二:检查 MediumType 配置兼容性

目标:确认 MediumType=128 是否为 OpenUBMC 支持的 SMBus_OEM 模式。

操作步骤

  1. 修改 Endpoint 配置尝试不同组合:
    "MediumType": 2   // 尝试标准 SMBus 而非 SMBus_OEM
    
  2. 重新启动 mctpd,测试 NC-SI 命令是否成功。
  3. 参考:
    | 协议               | MediumType |
    |--------------------|------------|
    | MCTP over PCIe     | 0x0F       |
    | MCTP over SMBus    | 0x02       |
    | MCTP over SMBus_OEM| 0x80 (128) |
    

:white_check_mark: 方案三:调试 smbus_write_read_service.lua

目标:确认响应是否在 Lua 层被正确接收并转发给 mctpd

操作步骤

  1. smbus_write_read_service.lua 中增加日志输出,打印所有 read 成功后的 buffer;
  2. 特别关注:
    if #data > 0 then
        print("SMBus READ -> ", to_hex(data))
    end
    
  3. 若读取到了数据但未上报给 mctpd,说明存在事件缺失。

:white_check_mark: 方案四:启用 mctpd 内部 trace 日志

目标:观察 mctpd 是否收到了 Response 消息。

操作

  1. 启用 mctpd 详细日志:
    busctl set-property bmc.kepler.mctpd.Debug Level s debug
    
  2. 或修改 init.lua 中 log level 为 DEBUG
  3. 检查日志中是否有类似:
    • mctp_engine: received packet from phy_addr=50
    • unhandled message type: 0x65

:white_check_mark: 方案五:升级或同步适配代码至最新稳定版本

  • 用户使用的是 master 分支,可能存在未修复 bug。
  • 建议:
    • 升级到官方发布的稳定版本(如含 SP1 的 2512);
    • 或对比《南向适配网迅网卡经验分享》文档中的 Endpoint 配置与驱动代码,保证一致性。

总结与结论

项目 分析结论
MCTP 控制通路是否正常 :white_check_mark: 正常,Set EID 成功,Endpoint 已创建
NC-SI 请求是否发出 :white_check_mark: 是,mctp::request() 成功触发
I2C 层是否收到响应 :white_check_mark: 是,返回 129 字节数据
根本原因定位 :red_question_mark: 主要在 MCTP 协议层处理逻辑,可能为:
1. 消息类型(MessageType)不匹配
2. MediumType 配置错误(SMBus_OEM 未支持)
3. smbus_write_read_service 未触发回调
4. mctpd 忽略了响应包
非 I2C 硬件问题 :white_check_mark: 排除物理层故障

推荐解决路径

  1. 立即行动
    • 使用 tracemctp 抓包分析 Response 的 MCTP Header。
  2. 核心验证
    • 确保 Message Type = 0x02,若非,请修改网卡行为。
  3. 配置调整
    • 尝试设置 MediumType = 2(标准 SMBus)替代 128
  4. 日志增强
    • smbus_write_read_service.luamctpd 中增加 trace 输出。
  5. 最终确认
    • 若上述无效,可尝试将 Hi182x 替换为已知兼容的网卡(如网迅 WX)做横向对比。

:hammer_and_wrench: 建议反馈给社区:百信-罗昊 等贡献者在类似问题(如 Topic 4949)中有丰富经验,可在其帖下引用此案例寻求进一步支持。

是必现的吗

必现的

请教《南向适配网迅网卡经验分享》的作者 @net_swift_tianwen 他没遇到这个情况。

按理来说,MCTP的控制报文Set EID能通,NC-SI over MCTP over SMBus,不应该在MCTP层出错。

MCTPD的源码没有开源,自己也没办法分析原因。:weary_face:

我正好在定位一个差不多的问题,也是mctp不通的,不过他那个是pcie的,而且是概率超时。我定位下那个问题的原因,再看看是不是同类问题。

好的,万分感谢。

补充OpenUBMC的启动app.log

app-260316-1.zip (38.7 KB)

好的,我看下