内核态数据通路架构:内核网络协议栈、RDMA子系统(ib_core)与数据包处理流程
核心原理:两条数据通路的本质分野
RDMA 与传统内核网络协议栈的根本差异,在于数据是否经过内核的通用网络协议栈(TCP/IP 处理链)。传统网卡收包后,数据依次经过驱动、协议栈(IP、TCP/UDP)、Socket 层,最终由用户态进程通过系统调用读取;而 RDMA 网卡(HCA)通过硬件卸载了传输层甚至网络层的部分工作,数据在用户态与网卡之间直接搬运,内核仅负责控制面(创建 QP、注册 MR、配置地址等)。
理解这一分野,需要先厘清内核中两个关键模块的职责边界:
- 内核网络协议栈(net stack):负责传统以太网数据包的收发、路由、分片重组、TCP 状态机等,其数据路径以
sk_buff为核心载体,处理链长、上下文切换多。 - RDMA 子系统(ib_core):位于内核驱动与上层协议(如 InfiniBand、RoCE、iWARP)之间,提供统一的设备管理、QP(Queue Pair)生命周期管理、MR(Memory Region)注册、事件分发等机制。它不参与数据搬运,但为数据搬运提供“轨道”和“信号灯”。
方法流程:ib_core 在内核中的注册与设备管理链路
RDMA 设备驱动(如 mlx5_ib)加载时,并非直接暴露给用户态,而是先向 ib_core 注册。其核心流程如下:
- 驱动探测与注册:PCI 驱动探测到 HCA 硬件后,调用
ib_register_device(),将struct ib_device注册进 ib_core 的设备列表。 - 设备能力上报:驱动填充
struct ib_device_attr(如最大 QP 数、MR 大小、原子操作能力、端口速率等),ib_core 据此向用户态导出设备能力。 - 字符设备创建:ib_core 为每个设备创建
/dev/infiniband/rdma_cm及/dev/infiniband/uverbs0等字符设备,用户态通过open()获取文件描述符。 - QP/MR 资源管理:用户态调用
ibv_create_qp()时,libibverbs 通过 ioctl 或 write 系统调用进入内核,ib_core 分配struct ib_qp并调用驱动提供的create_qp回调,最终在硬件中创建队列对。
发送路径:
用户态写 WQE (Work Queue Element) → 硬件 DMA 读取数据
→ HCA 封装 RoCE v2 头 (ETH+IP+UDP+BTH)
→ 从网口发出
接收路径:
网口收到 RoCE v2 包 → HCA 解析 BTH 找到 QP
→ 硬件 DMA 将 payload 写入用户预先注册的 MR
→ 在 CQ 中产生 CQE → 用户态 poll CQ 获取完成通知
值得注意的是,RoCE v2 的报文会物理上经过网卡,但内核协议栈完全看不到这些数据包——因为 HCA 在硬件层面完成了 L2/L3/L4 的处理,仅当发生异常(如 QP 错误、流控问题)时,驱动才会将事件上报给 ib_core,进而通知用户态。
案例场景:多网卡共存时的数据通路隔离
在一台同时配置了传统以太网卡(如 eno1)和 RoCE 网卡(如 ens2f0)的服务器上,数据通路的隔离性体现得尤为明显:
| 操作 | 传统网络 (TCP) | RDMA (RoCE) |
|---|---|---|
| IP 配置 | 内核网络栈管理 ip addr add |
ib_core 关联 IP,但数据不经过内核 IP 栈 |
| 数据发送 | 应用 → Socket → TCP → IP → 驱动 → NIC | 应用 → WQE → HCA 硬件直接封装发送 |
| 数据接收 | NIC → 驱动 → 协议栈 → Socket → 应用 | HCA → DMA → 用户内存 → CQE 通知 |
| CPU 参与 | 每个包均产生中断/软中断,CPU 拷贝多次 | 仅创建 QP/MR 时 CPU 参与,数据面零拷贝 |
| 错误处理 | 内核协议栈重传、ICMP 差错 | HCA 硬件重传,QP 进入 ERROR 状态后上报 ib_core |
实际部署中,若使用 ip route 将 RoCE 网卡的 IP 指向网关,传统 TCP 流量可能误入 RoCE 网卡,导致性能骤降——因为 RoCE 网卡虽然支持以太网帧,但其驱动默认将 ETH_P_IB 之外的包丢弃或慢路径处理。此时需要显式配置 rdma_cm 或使用 tc 分流,确保两类流量各走各的物理端口。
误区与复盘:内核态数据通路的常见误解
实际上,控制面(设备打开、QP 建立、内存注册、中断处理)必须经过内核 ib_core。只有数据面(post_send / poll_cq)可以做到用户态直通硬件。若完全绕过内核,则无法利用内核的内存管理、安全隔离和资源调度能力。
RoCE 的 data path 是内核旁路,但 RoCE 的 ARP 解析、GID 索引管理仍依赖内核网络栈(例如
ip route 和 rdma link 的协同)。iWARP 则更特殊——其 DDP 层映射到 TCP,因此数据面虽然绕过内核 Socket,但 TCP 状态机仍由内核维护(或由硬件 TCP 卸载引擎处理)。
复盘建议:排查 RDMA 性能问题时,不要只盯着用户态代码。先用 rdma link show 确认链路状态,用 ibstat 查看 HCA 端口速率,再用 perf 观察是否有大量 ib_core 相关软中断——若软中断占比过高,说明驱动或 ib_core 配置存在瓶颈(如中断合并参数 moderation 设置不当)。
- 检查
/sys/class/infiniband/mlx5_0/ports/1/rate确认链路速率未降级。 - 通过
echo 0 > /sys/class/infiniband/mlx5_0/ports/1/rate无法调速,需用mlxconfig或ethtool调整。 - 观察
cat /proc/interrupts中 HCA 中断是否均衡分布在多个 CPU 上,必要时设置irqbalance或手动绑定。