4. 主机与 DPU 通信机制

BlueField DPU 在系统中同时扮演两个角色:对主机而言,它是一张插在 PCIe 插槽上的多功能设备;对自身而言,它又是一台运行 Linux 的独立 ARM 服务器。主机与 DPU 之间的所有交互,最终都要落到这几条物理与逻辑通道上:PCIe 配置空间与 BAR、RShim 寄存器通道、虚拟网络接口、RPC 调用,以及共享内存与消息传递。理解它们的层次关系,是后续做固件升级、网络卸载、存储卸载和带外管理的基础。

一、PCIe 枚举:主机如何“看见”DPU

DPU 上电后,主机 BIOS 或操作系统在 PCIe 枚举阶段扫描总线,读取每个功能的 Vendor ID 和 Device ID。BlueField-2 的典型标识是 15b3(Mellanox)与 a2d6(BlueField-2 SoC),BlueField-3 则对应 a2dc 等。枚举完成后,主机为每个功能分配总线号、设备号、功能号(BDF)以及 BAR 空间。可以用下面的命令确认枚举结果:

lspci -nn | grep -i mellanox
# 01:00.0 Ethernet controller [0200]: Mellanox ... BlueField-2 [15b3:a2d6]
# 01:00.1 ... [15b3:a2d6]
# 01:00.2 ... [15b3:a2d6]
# 01:00.3 ... [15b3:a2d6]
lspci -vv -s 01:00.0 | grep -E "Region|Capabilities"

这里有一个关键点:DPU 的 PCIe 功能通常被划分为多个 PF(Physical Function),其中一部分归主机使用(如网卡 PF、NVMe PF),另一部分归 DPU 自身 ARM 侧使用。枚举时主机只能看到分配给自己的功能,DPU 侧的功能由 DPU 内部的 PCIe 控制器枚举。因此“主机看到的 DPU”和“DPU 看到的自己”是两套视角,排查问题时必须区分。

二、RShim 驱动:带外控制与引导通道

RShim(Register Shim)是 BlueField 提供的一条轻量级控制通道,主机通过它访问 DPU 的引导寄存器、控制台和部分状态寄存器。在主机侧,RShim 通常以 PCIe 设备形式出现,加载 rshim 驱动后生成 /dev/rshim0 设备节点;在 DPU 侧,RShim 也可以走 USB 或 PCIe。它的典型用途包括:向 DPU 推送 boot stream、复位 DPU、读取启动日志。

# 主机侧查看 RShim 设备
ls /dev/rshim*
cat /dev/rshim0/misc
# 推送 boot stream(示例)
cat bf-bundle-*.img > /dev/rshim0/boot
# 读取 DPU 控制台输出
cat /dev/rshim0/console

RShim 的价值在于“主机可以在 DPU 操作系统尚未启动时就开始干预”。当 DPU 的 ARM 侧系统崩溃、网络不通时,RShim 往往是唯一还能用的通道。需要注意的是,RShim 的寄存器访问是字节流式的,不适合传输大块数据,因此它只承担引导和控制,不承担业务数据面。

三、虚拟网络接口:数据面的主通道

主机与 DPU 之间最常用的数据通道是虚拟网络接口。典型形态有两种:一是 SR-IOV 虚拟功能(VF),主机侧看到的是 ens1f0v0 之类的 VF 网口,DPU 侧对应一个 representor;二是 virtio-net 或 veth 形式的虚拟链路,用于控制面或轻量数据。以 SR-IOV 为例,主机侧配置 VF 后,DPU 侧通过 representor 可以观察和控制该 VF 的流量:

# 主机侧创建 VF
echo 4 > /sys/class/net/ens1f0/device/sriov_numvfs
ip link show ens1f0v0
# DPU 侧查看 representor
ip link show | grep -i representor

这条通道的特点是“主机以为自己在用一张普通网卡,实际流量被 DPU 接管”。DPU 可以在 representor 上做 ACL、镜像、转发、卸载,而主机侧无需修改应用。这也是 DPU 实现网络卸载的核心机制。

四、RPC、共享内存与消息传递:控制面的协作方式

除了数据面,主机与 DPU 还需要交换控制信息,例如下发卸载规则、查询统计、同步配置。常见方式有三类:

  • RPC:DPU 侧运行 gRPC 或自定义 RPC 服务,主机通过 PCIe 上的网络接口或 RShim 通道调用。适合请求-响应式、低频、结构化的控制命令。
  • 共享内存:主机与 DPU 通过 PCIe BAR 映射一段内存,双方按约定结构读写。适合高频、低延迟的状态同步,但必须自己处理一致性和同步。
  • 消息传递:基于 ring buffer 或队列,主机写入描述符,DPU 轮询或中断处理。适合批量事件、日志、统计上报。

三者的选择依据是:延迟要求、数据量、是否需要可靠应答。控制命令用 RPC,状态同步用共享内存,事件流用消息传递,是实践中比较常见的组合。

主机与 BlueField DPU 通信通道分层视图 主机侧 (x86 Host) PCIe 枚举 / BDF / BAR lspci · 15b3:a2d6 RShim 驱动 /dev/rshim0 · boot/console 虚拟网络接口 (VF) ens1f0v0 · SR-IOV RPC 客户端 gRPC / 自定义协议 共享内存映射 BAR mmap · 状态同步 消息队列 / Ring Buffer DPU 侧 (ARM SoC) PCIe 控制器 / PF 内部枚举 · 功能划分 RShim 寄存器 引导 / 复位 / 控制台 Representor 网口 ACL · 镜像 · 转发 RPC 服务端 卸载规则 / 统计查询 共享内存区 一致性 / 同步原语 消息处理 / 事件循环 配置空间读写 boot stream / console 业务数据面 (VF ↔ representor) 请求 / 响应 mmap 读写 描述符 / 事件 控制面:RShim / RPC / 共享内存 · 数据面:VF / 消息队列

五、通道选择与排障要点

实际工作中,判断该用哪条通道,可以按下面的顺序思考:如果 DPU 系统还没起来,只能用 RShim;如果要做网络卸载,走 VF 与 representor;如果要下发控制规则,走 RPC;如果要高频同步状态,走共享内存;如果要上报事件,走消息队列。排障时也要按这个顺序逐层确认:先看 lspci 是否枚举到设备,再看 /dev/rshim0 是否存在,再看 VF 与 representor 是否成对出现,最后才检查 RPC 服务是否可达、共享内存是否映射成功。

一个常见误区是:主机侧 ip link 能看到 VF,就认为 DPU 侧一定配置好了。实际上 VF 只是 PCIe 功能,representor 才是 DPU 侧真正接管流量的对象。两者必须同时存在且状态一致,卸载才能生效。

把这几条通道的关系理清之后,后续无论是做 OVS 卸载、NVMe-oF 卸载,还是做 DPU 上的容器网络,都能快速定位问题出在枚举、驱动、数据面还是控制面。