1. 整体架构
本文以 Linux、rdma-core 和 mlx5 为分析对象,围绕 RC QP、普通 verbs、主机内存与 RoCEv2,介绍各层的职责和接口。rdma-core 是用户态项目,RDMA Core 是 Linux 内核中的 RDMA 通用层。
RDMA 软件栈分为五层:应用组织通信任务,用户态库提供 API 和设备相关操作,内核管理设备与资源,mlx5 驱动实现通用接口与具体设备,HCA 根据配置访问内存并执行请求。
需区分资源建立与正常收发:资源请求经内核完成校验和配置;资源建立后,普通 mlx5 用户态收发及 CQ 轮询直接由 provider 执行,内核态收发由 mlx5_ib 执行。librdmacm 与 ucma 提供连接管理路径。

2. 应用层
User Application 负责分配业务缓冲区,创建 PD、MR、QP、CQ 等资源,提交 WR,并根据 WC 处理通信结果和回收资源。应用通过 WR 描述请求,通过 WC 获得相应的完成结果。
3. 用户态库
用户态库提供通用 API,并把设备相关操作交给对应 provider。
| 组件 | 作用与功能 | 对外接口 |
|---|---|---|
| libibverbs | 提供通用 verbs API,发现设备、匹配 provider,管理 context,并提供资源命令和事件接口。 | ibv_open_device()、ibv_reg_mr()、ibv_create_qp()、ibv_post_send()、ibv_post_recv()、ibv_poll_cq() 等。 |
| mlx5 provider | 实现 mlx5 的用户态功能,管理队列缓冲区,构造 WQE、解析 CQE,访问设备映射区域等。 | 向 libibverbs 注册 provider 操作表;控制请求使用 ibv_cmd_*,正常收发使用队列内存和 MMIO。 |
| librdmacm | 提供地址、路由和连接管理,向应用提供管理功能。 | rdma_create_id()、rdma_resolve_addr()、rdma_connect()、rdma_get_cm_event() 等。 |
libibverbs 负责通用接口,mlx5 provider 负责实现具体设备的功能。librdmacm 通过 RDMA CM 设备文件与内核交互,需要创建 QP 时仍使用 verbs 资源接口。
4. 内核服务
内核服务负责校验用户请求、管理 RDMA 设备和对象,并向用户态与内核消费者提供统一的资源及通信接口。
| 组件 | 作用与功能 | 对外接口 |
|---|---|---|
| uverbs | 承接用户态资源请求,校验命令与句柄,管理用户对象、映射,以及 CQ 通知和异步事件通道。 | /dev/infiniband/uverbsN 的 ioctl、legacy write、mmap;事件通道 fd 的 read、poll 接口。 |
| ucma | 承接用户态连接管理请求,将请求交给内核 RDMA CM,并返回连接事件。 | /dev/infiniband/rdma_cm。 |
| RDMA Core / Kernel Verbs | 注册和管理 RDMA 设备,提供通用对象、内存管理及内核 verbs;由设备操作表连接具体驱动。 | ib_device、ib_device_ops,以及 ib_create_qp()、ib_post_send()、ib_poll_cq() 等。 |
| Kernel Consumers(使用者) | 如 NVMe/RDMA,是 RDMA Core 的调用方。 | 使用内核 verbs 管理资源、提交请求并处理完成事件。 |
内核服务还负责向相应消费者交付事件。uverbs 的事件通道以文件描述符(fd)提供给用户态:应用通过 ibv_get_cq_event() 读取 completion channel 的 CQ 通知,通过 ibv_get_async_event() 读取 QP/CQ 错误、端口状态变化等异步事件。这两个接口内部通过 read 从对应 fd 读取事件,也可先通过 poll 等待 fd 可读。CQ 通知提示应用检查队列,具体 WC 由 ibv_poll_cq() 获取;连接事件由 librdmacm 的 rdma_get_cm_event() 单独获取。
5. mlx5 驱动
mlx5_ib 是 RDMA 设备驱动,负责把通用 RDMA 对象和请求转换为 mlx5 资源配置,管理 MR、QP、CQ 等对象,并实现内核态收发与 CQ 处理。它通过 ib_device_ops 向 RDMA 通用层提供资源管理和收发操作,向下使用 mlx5_core 的命令和公共设备服务。
mlx5_core 管理 mlx5 设备的公共设施,包括 PCI 设备、BAR、设备能力、固件命令、EQ 和 IRQ。它向 mlx5_ib 等功能驱动提供设备访问、命令执行与事件分发接口,代表性接口为 mlx5_cmd_exec()。
两者在控制和数据路径中的分工有所不同:资源建立需要驱动配置设备;通过 mlx5_ib 操作队列与 MMIO 完成内核态数据收发,设备事件则由 mlx5_core 接收并分发给对应处理器。
6. 硬件与内存
HCA 按照软件对 QP、CQ 和内存访问的配置执行 RDMA 请求,通过 DMA 访问主机内存,并将 CQE 写入 CQ。软件通过设备命令配置资源,通过 MMIO 等设备接口通知 HCA 执行请求,通过 CQ 获取完成结果,并按需接收事件通知。
Host Memory 承载队列、doorbell record 和业务缓冲区。软件在 CPU 上将 WR 编码为 WQE,并解析 CQE、结合请求信息生成 WC;HCA 按请求访问已注册的业务内存。图中的 Host Memory 汇总了两类消费者各自管理的队列与缓冲区。
应用还需区分本地完成和远端应用处理:成功的本地 WC 表示相应操作满足接口规定的完成条件,远端应用是否已经消费数据由应用协议确认。
7. 参考资料
7.1 源码位置
以下目录相对于 rdma-core/ 与 linux/ 所在的共同父目录;目录与文件名组合即为代码位置。
| 层与功能 | 相对目录 | 文件 |
|---|---|---|
| 应用层:RC 通信例程 | rdma-core/libibverbs/examples/ | rc_pingpong.c |
| 用户态库:verbs API、设备发现与分发 | rdma-core/libibverbs/ | verbs.h、driver.h、init.c、device.c、verbs.c |
| 用户态库:资源命令封装 | rdma-core/libibverbs/ | cmd.c、cmd_mr.c、cmd_qp.c、cmd_cq.c、cmd_fallback.c |
| 用户态库:mlx5 provider | rdma-core/providers/mlx5/ | mlx5.c、mlx5.h、verbs.c、qp.c、cq.c、buf.c、dbrec.c |
| 用户态库:连接管理 | rdma-core/librdmacm/ | cma.c、rdma_cma.h |
| 内核服务:uverbs ABI 与用户资源 | linux/drivers/infiniband/core/ | uverbs_main.c、uverbs_ioctl.c、uverbs_cmd.c、uverbs_std_types_cq.c |
| 内核服务:用户/内核 ABI 定义 | linux/include/uapi/rdma/ | ib_user_verbs.h、ib_user_ioctl_cmds.h、rdma_user_cm.h |
| 内核服务:设备、对象、内存与 CQ 管理 | linux/drivers/infiniband/core/ | device.c、verbs.c、rdma_core.c、umem.c、cq.c |
| 内核服务:内核 verbs 接口 | linux/include/rdma/ | ib_verbs.h、ib_umem.h |
| 内核服务:连接管理 | linux/drivers/infiniband/core/ | ucma.c、cma.c |
| 内核服务:NVMe/RDMA 消费者 | linux/drivers/nvme/host/、linux/drivers/nvme/target/ | 两个目录中的 rdma.c |
| mlx5 驱动:RDMA 资源与内核收发 | linux/drivers/infiniband/hw/mlx5/ | main.c、mlx5_ib.h、qp.c、qpc.c、mr.c、wr.c、cq.c |
| mlx5 驱动:设备、命令与事件 | linux/drivers/net/ethernet/mellanox/mlx5/core/ | main.c、dev.c、cmd.c、eq.c、cq.c、uar.c |
| 硬件与内存:软件可见的设备格式与接口 | linux/include/linux/mlx5/ | mlx5_ifc.h、device.h、doorbell.h |
7.2 官方文档
- Linux Kernel Documentation,Userspace verbs access:linux/Documentation/infiniband/user_verbs.rst,介绍用户态 verbs 访问与内核资源管理的基本分工。
- rdma-core,libibverbs 文档:rdma-core/Documentation/libibverbs.md,介绍用户态 verbs 库及设备访问要求。
- librdmacm,
rdma_cm(7):rdma-core/librdmacm/man/rdma_cm.7,介绍连接管理接口及其与 verbs 的关系。 - libibverbs,
ibv_get_cq_event(3)与ibv_poll_cq(3):rdma-core/libibverbs/man/ibv_get_cq_event.3、rdma-core/libibverbs/man/ibv_poll_cq.3,说明 CQ 通知与完成结果的区别。