RDMA OpenSM 架构、软件实现与应用
knowledge base:
RDMA: libibverbs 架构及其与内核 uverbs 的交互机制
一、RDMA 基础架构
1.1 什么是 RDMA
RDMA(Remote Direct Memorial Access,远程直接内存访问)是一种允许网络中一台计算机直接访问另一台计算机内存的技术,无需 CPU 介入、无需操作系统内核参与数据路径。
传统网络路径:
App → 用户态Buffer → 系统调用 → 内核协议栈 → 网卡驱动 → 网络
RDMA 路径:
App → 注册内存区域(MR) → RDMA NIC(RNIC) → 网络(内核旁路)
1.2 RDMA 三大传输协议
| 协议 | 全称 | 链路层 | 特点 |
|---|---|---|---|
| InfiniBand | IB | 专用IB网络 | 性能最强,延迟最低,需专用交换机 |
| RoCE | RDMA over Converged Ethernet | 以太网 | v1基于L2,v2基于UDP/IP,复用以太网 |
| iWARP | Internet Wide Area RDMA Protocol | TCP/IP | 兼容性强,性能稍弱 |
1.3 核心操作语义
单边操作(Zero-copy,无需远端CPU):
RDMA READ — 从远端内存读取数据
RDMA WRITE — 向远端内存写入数据
RDMA ATOMIC — 原子操作(CAS/FAA)
双边操作(需远端CPU参与):
SEND / RECV — 类似传统消息传递
二、InfiniBand 网络架构
2.1 IB 网络拓扑组件
┌──────────────────────────────────────────────────┐
│ InfiniBand Fabric │
│ │
│ Host A Host B │
│ ┌──────┐ ┌──────────────┐ ┌──────┐ │
│ │ HCA │────│ IB Switch │───│ HCA │ │
│ └──────┘ └──────┬───────┘ └──────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ │ IB Switch │ │
│ └──────┬───────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ │ SM (OpenSM) │ ← Subnet Manager │
│ └──────────────┘ │
└──────────────────────────────────────────────────┘
2.2 IB 地址体系
| 地址类型 | 说明 |
|---|---|
| GID | Global Identifier,128位,全局唯一 |
| LID | Local Identifier,16位,子网内唯一,由SM分配 |
| GUID | 64位,硬件固化,类似MAC地址 |
| PKEY | Partition Key,逻辑隔离分区 |

三、OpenSM 架构详解
3.1 OpenSM 定位
OpenSM 是 Linux 平台上开源的 InfiniBand Subnet Manager(SM) 实现,属于 rdma-core / opensm 项目,由 OFED(OpenFabrics Enterprise Distribution)维护。
SM 是 IB 网络的”大脑”,负责发现拓扑、分配地址、计算路由、管理状态。
3.2 OpenSM 核心子系统
┌─────────────────────────────────────────────────────────┐
│ OpenSM │
│ │
│ ┌───────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ Subnet │ │ Routing │ │ Event │ │
│ │ Manager │ │ Engine │ │ Manager │ │
│ └─────┬─────┘ └──────┬───────┘ └───────┬───────┘ │
│ │ │ │ │
│ ┌─────▼────────────────▼────────────────────▼──────┐ │
│ │ Core State Machine │ │
│ └─────────────────────┬─────────────────────────── ┘ │
│ │ │
│ ┌─────────────────────▼──────────────────────────────┐ │
│ │ MAD (Management Datagram) Layer │ │
│ └─────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌─────────────────────▼──────────────────────────────┐ │
│ │ libibmad / libibumad │ │
│ └─────────────────────┬──────────────────────────────┘ │
│ │ │
└────────────────────────┼────────────────────────────────┘
│
IB Hardware (HCA)
3.3 OpenSM 工作流程
Phase 1: 发现(Discovery)
SM 发送 SMP (Subnet Management Packets)
遍历所有交换机端口,构建拓扑图
Phase 2: 地址分配(Address Assignment)
为每个端口分配唯一 LID
写入各节点的 PortInfo 属性
Phase 3: 路由计算(Routing)
根据拓扑选择路由算法(min-hop/ftree/lash等)
生成 LFT(Linear Forwarding Table)
下发至所有交换机
Phase 4: 激活(Activation)
将所有端口状态迁移到 ACTIVE
子网进入可用状态
Phase 5: 持续监控(Event-driven maintenance)
监听 Trap 事件
处理端口上/下线,触发重新路由
3.4 OpenSM 路由算法
| 算法 | 适用场景 | 特点 |
|---|---|---|
min_hop |
通用默认 | 最短路径,简单高效 |
ftree |
Fat-Tree 拓扑 | 针对HPC胖树网络优化,负载均衡 |
lash |
多路径 | 消除死锁,利用虚通道 |
updn |
非规则拓扑 | Up/Down 路由,避免环路 |
dgree |
大规模集群 | 分布式路由计算 |
dfsssp |
通用 | 基于Dijkstra最短路径 |
四、软件栈实现
4.1 Linux RDMA 软件栈层次
用户态应用
│
▼
┌──────────────────────────────────────┐
│ 用户态库 (libibverbs) │ ← verbs API
│ libmlx5 / librdmacm / libmad │
└──────────────────┬───────────────────┘
│ ioctl / mmap
┌──────────────────▼───────────────────┐
│ 内核态 RDMA 子系统 │
│ ib_core / rdma_cm / ib_uverbs │
├──────────────────────────────────────┤
│ 驱动层 │
│ mlx5_core / mlx4 / rxe(软件RoCE) │
└──────────────────┬───────────────────┘
│
RDMA 硬件 (HCA/RNIC)
4.2 关键库与工具
# 核心库
libibverbs # 统一 verbs 接口
librdmacm # 连接管理(类socket)
libibmad # MAD 报文处理
libibumad # 用户态 MAD 访问
# OpenSM 相关
opensm # Subnet Manager 主程序
osmtest # SM 功能测试工具
# 诊断工具
ibstat # 查看HCA状态
ibstatus # 端口链路状态
ibroute # 查看路由表
ibtracert # 路径追踪
perfquery # 性能计数器查询
ibping # 网络连通测试
4.3 OpenSM 安装与启动
# 安装(RHEL/CentOS)
yum install opensm opensm-libs
# 安装(Ubuntu/Debian)
apt install opensm
# 启动
systemctl start opensm
systemctl enable opensm
# 手动启动(指定端口GUID)
opensm -g 0x0002c9030000f1e1 \
-f /var/log/opensm.log \
-R ftree \ # 路由算法
--priority 8 # SM优先级(0-15,越高越优先)
4.4 OpenSM 配置文件
# /etc/opensm/opensm.conf(关键配置项)
# 路由算法
routing_engine ftree
# 日志级别
log_flags 0x03
# SM 优先级(多SM部署时使用)
sm_priority 8
# 扫描周期(秒)
sweep_interval 10
# 开启 SR-IOV 支持
enable_sr_iov TRUE
# Partition 配置文件
partition_config_file /etc/opensm/partitions.conf
4.5 Partition(分区)配置
# /etc/opensm/partitions.conf
# 格式: PartitionName=PKEY, [ipoib]: GUIDlist
Default=0x7fff, ipoib:
ALL_CAS=full; # 所有CA端口加入默认分区
Storage=0x0002, ipoib:
0x0002c9030000f1e0=full, # 存储节点
0x0002c9030000f1e2=full;
Compute=0x0003, ipoib:
0x0002c9030000f1e4=full, # 计算节点
0x0002c9030000f1e6=full;
五、核心编程接口(Verbs API)
5.1 RDMA 连接建立流程
// 1. 获取设备列表
struct ibv_device **dev_list = ibv_get_device_list(&num_devices);
// 2. 打开设备
struct ibv_context *ctx = ibv_open_device(dev_list[0]);
// 3. 分配 Protection Domain
struct ibv_pd *pd = ibv_alloc_pd(ctx);
// 4. 注册内存区域(MR)
struct ibv_mr *mr = ibv_reg_mr(pd, buf, buf_size,
IBV_ACCESS_LOCAL_WRITE |
IBV_ACCESS_REMOTE_READ |
IBV_ACCESS_REMOTE_WRITE);
// 5. 创建 Completion Queue
struct ibv_cq *cq = ibv_create_cq(ctx, CQ_SIZE, NULL, NULL, 0);
// 6. 创建 Queue Pair(QP)
struct ibv_qp_init_attr qp_attr = {
.send_cq = cq,
.recv_cq = cq,
.qp_type = IBV_QPT_RC, // Reliable Connection
.cap = { .max_send_wr = 64, .max_recv_wr = 64 }
};
struct ibv_qp *qp = ibv_create_qp(pd, &qp_attr);
// 7. QP 状态迁移: RESET → INIT → RTR → RTS
// (需交换 QPN、LID、GID 等握手信息)
5.2 RDMA WRITE 操作示例
// 构建 WRITE 工作请求
struct ibv_sge sge = {
.addr = (uint64_t)local_buf,
.length = msg_len,
.lkey = mr->lkey // 本地内存key
};
struct ibv_send_wr wr = {
.wr_id = 1,
.opcode = IBV_WR_RDMA_WRITE,
.sg_list = &sge,
.num_sge = 1,
.send_flags = IBV_SEND_SIGNALED,
.wr.rdma = {
.remote_addr = remote_addr, // 对端虚拟地址
.rkey = remote_rkey // 对端内存key
}
};
// 提交到发送队列
struct ibv_send_wr *bad_wr;
ibv_post_send(qp, &wr, &bad_wr);
// 轮询完成队列
struct ibv_wc wc;
while (ibv_poll_cq(cq, 1, &wc) == 0);
// wc.status == IBV_WC_SUCCESS 表示成功
六、典型应用场景
6.1 HPC 高性能计算
MPI 通信库(OpenMPI / MPICH)
│
UCX 传输框架
│
libibverbs (RDMA)
│
InfiniBand Fabric (OpenSM 管理)
特点:
- MPI_Send/Recv 透明利用 RDMA
- 延迟 < 1μs,带宽 > 200Gbps(HDR IB)
- 支持 AllReduce 等集合操作硬件卸载
6.2 分布式存储
| 系统 | RDMA 使用方式 |
|---|---|
| Ceph | BlueStore + RDMA messenger |
| DAOS | 全RDMA,专为NVM-oF设计 |
| Lustre | LNet over IB/RoCE |
| GlusterFS | RDMA transport |
| NVMe-oF | 块设备通过RDMA访问 |
6.3 AI/ML 训练加速
多GPU训练通信栈:
PyTorch DDP / NCCL
│
UCX / NCCL-RDMA
│
RoCEv2 / InfiniBand
│
OpenSM (IB) / 交换机配置 (RoCE)
关键技术:
- GPUDirect RDMA:GPU内存直接DMA到网卡,绕过CPU
- SHARP (Scalable Hierarchical Aggregation):交换机内AllReduce
- 带宽:NDR InfiniBand 400Gbps/端口
6.4 云计算与虚拟化
# SR-IOV 虚拟化(一张物理HCA切分为多个VF)
echo 8 > /sys/class/infiniband/mlx5_0/device/mlx5_num_vfs
# DPDK + RDMA 用户态网络
# RoCE 在公有云(AWS EFA, Azure InfiniBand)
七、高可用与多 SM 部署
主备 SM 选举机制(基于 SM Priority + GUID):
SM_A (priority=8) ──┐
├── 通过 SMInfo MAD 选主
SM_B (priority=6) ──┘ priority高者成为Master SM
相同priority则GUID大者胜出
Master SM:负责完整子网管理
Standby SM:监听Master心跳,随时准备接管
配置示例:
# SM_A(主)
opensm --priority 8 --guid 0x...a
# SM_B(备)
opensm --priority 6 --guid 0x...b
八、监控与诊断
# 查看子网拓扑
ibnetdiscover -p # 打印完整拓扑
ibnetdiscover > topo.txt # 保存拓扑
# 查看路由表
ibroute <switch_lid> # 查看交换机LFT
# 性能监控
perfquery <lid> <port> # 端口计数器
ibclearerrors -a # 清除错误计数
# 链路质量诊断
ibqueryerrors # 全网错误扫描
iblinkinfo # 链路速率信息
# 路径追踪
ibtracert <src_lid> <dst_lid> # 追踪报文路径
# OpenSM 日志分析
tail -f /var/log/opensm.log | grep -E "ERR|WRN|routing"
九、总结
RDMA 生态全景:
物理层:InfiniBand / RoCEv2 / iWARP
↓
网络管理:OpenSM(拓扑发现、LID分配、路由计算)
↓
驱动层:mlx5_core / ib_core(内核)
↓
用户态:libibverbs / librdmacm
↓
中间件:UCX / MPI / SPDK / DPDK
↓
应用:HPC / AI训练 / 分布式存储 / 低延迟数据库
OpenSM 作为 IB 子网的控制平面,是整个 RDMA 网络正常运作的前提。理解其拓扑发现、路由计算、事件处理机制,对于部署、调优和排障大规模 RDMA 集群至关重要。


夜雨聆风