RDMA-Toy-0 环境简单搭建

RXE 是 Linux 上的“软件 RoCE v2 驱动”(内核模块 rdma_rxe),让普通以太网接口具备 RDMA 能力(走内核网络栈)。RoCE v2 将 RDMA 负载封装在 UDP/IPv4 或 UDP/IPv6 中,默认目的端口 4791。设备/驱动通常把到 4791 的流量识别为 RoCE。本文旨在用同一台主机、不依赖硬件 RNIC,搭出一套可复现且稳定的 RDMA 实验环境:rping、perftest均可跑通。

实验环境介绍

系统:Debian testing(个人喜用testing分支,任一较新内核的 Debian/Ubuntu 均可),软件包(发行版自带,避免混装第三方 OFED):

1
2
sudo apt update
sudo apt install -y rdma-core ibverbs-providers rdmacm-utils perftest ethtool nftables

实验环境搭建

思路:在宿主机创建一对二层直连的虚拟网卡 vA/vB,分别配置 IPv4,再把它们各自绑定为 rxe0/rxe1。这样路径最短、变量最少,最利于复现与排障。

  1. 清理残留(可以反复执行)
1
2
3
4
5
6
7
8
9
10
# 停掉可能残留的测试进程
sudo pkill -f 'rping|ibv_|ib_write_bw|ib_read_bw|ib_send_bw' 2>/dev/null || true
# 删除历史 veth/macvlan/ipvlan
for nic in vA vB mvl0 mvl1 ivl0 ivl1; do sudo ip link del "$nic" 2>/dev/null || true; done
# 删除历史 rxe/siw 设备并卸载模块
for dev in $(sudo rdma link show 2>/dev/null | awk '/link (rxe|siw)/{print $2}'); do sudo rdma link delete "$dev"; done
sudo modprobe -r rdma_rxe 2>/dev/null || true
# 清空本机 nftables(避免拦截 UDP/4791)
sudo nft flush ruleset 2>/dev/null || true

  1. 创建veth对
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sudo ip link add vA type veth peer name vB
sudo ip addr add 10.10.0.1/24 dev vA
sudo ip addr add 10.10.0.2/24 dev vB
sudo ip link set vA up
sudo ip link set vB up

# 关闭聚合,减少后续 RXE 的不确定性
sudo ethtool -K vA gro off gso off tso off 2>/dev/null || true
sudo ethtool -K vB gro off gso off tso off 2>/dev/null || true

# 放宽反向路由校验(仅对这两个接口)
sudo sysctl -w net.ipv4.conf.vA.rp_filter=0
sudo sysctl -w net.ipv4.conf.vB.rp_filter=0

# 基本连通性(预期均为成功)
ping -c1 -I vA 10.10.0.2
ping -c1 -I vB 10.10.0.1

▸ 为什么先验证 ping?
这一步确保二层(ARP)与三层(ICMP)基本无拦截;若此时 rping 能通而 ping 不通,通常是规则屏蔽了 ICMP 而并未影响 UDP/4791,详见NVIDIA DOC

▸ 为什么要关闭聚合,以及为什么?
在 veth/macvlan/ipvlan 这类纯软件路径上做 Soft-RoCE 实验时,建议 ethtool -K gro off gso off tso off。
这么做的目的有两个:

  • 保证一条 UDP 报文 ≈ 一个内核 skb,不被合并/延后处理;
  • 避免“虚拟网卡 + 分段/聚合”带来的时序抖动与特殊 skb 形态,从而使 rxe 的收发、流控与超时行为更可预测,可复现。

WHY:

  • TSO(TCP Segmentation Offload)/GSO(Generic Segmentation Offload)
    发送端把一段很大的逻辑报文(大于 MTU)打成一个大 skb下发,交由后续层(通常是网卡或协议子层)再分片成多个 MTU 大小的帧。GSO 是可作用于 UDP 等非 TCP 场景;TSO 是网卡分段的特定形式。
  • GRO(Generic Receive Offload)/ LRO
    接收端把多个属于同一流的连续小包在内核合并为一个更大的 skb,以减少上层处理次数。GRO 是内核通用聚合,LRO 是网卡侧的聚合。在物理网卡场景中,这些特性通常有利于吞吐;但在纯软件路径(veth 等)上,它们会引入额外的合并/分段时机与非 MTU 粒度的 skb 形态。

RoCEv2 把 RDMA 负载封进 UDP;rxe 在内核处理 UDP/4791 的收发,将每个RoCE BTH 单元映射为数据平面的动作(QP/PSN、RNR/ACK/NAK、CQE 产生等)。期望是报文到达的时间序列尽量贴近发送端真实节奏。

多个连续 UDP 报文可能被 GRO 合成一个带分段信息的 skb(如 skb 的 fraglist 或 GRO segment list),最后在一次 NAPI 轮询里一次性交给上层。

对 rxe 来说,改变了包到达的时间分布(排队论):本来应该“均匀到达”的 WQE 相关报文,会成批出现。副作用是对接收侧 CQE 瞬时压力增大,容易触发RNR(Receiver Not Ready),导致发送侧重试;发送侧若启用 GSO/TSO,可能把多 MTU 的数据打成一个大 skb交给 veth;veth 的对端再在某个时刻统一分段。导致不是每次立刻按 MTU 发送,而是攒批分段。副作用是对端看到的包间隔不均匀,ACK/NAK 的时序也随之改变;对 RDMA RC(可靠连接)这种对超时、窗口非常敏感的传输来说,会放大实验不可重复性。

  1. 启用Soft-RoCE
1
2
3
4
5
6
7
8
9
10
11
sudo modprobe rdma_rxe
sudo rdma link add rxe0 type rxe netdev vA
sudo rdma link add rxe1 type rxe netdev vB

# 预期:state ACTIVE / LINK_UP
sudo rdma link show

# 查看 GID(用于后续 perftest 选择)
ibv_devinfo -d rxe0 -v | grep -i 'GID\[\s*1\]'
ibv_devinfo -d rxe1 -v | grep -i 'GID\[\s*1\]'

这里看到的 GID 是什么?

  • GID[0] 为 IPv6 链路本地(fe80::…);
  • GID[1] 为 IPv4-mapped IPv6(形如 ::ffff:10.10.0.x)。RoCE/Soft-RoCE 在小规模实验中经常选 GID[1] 来与 IPv4 地址对应。

链路验证

  1. RDMA_CM(rping):
1
2
3
4
# 服务端: 10.10.0.1
sudo rping -s -a 10.10.0.1 -p 18515 -v -d
# 客户端: 10.10.0.2 一侧,指向 .1
sudo rping -c -a 10.10.0.1 -p 18515 -v -d

服务端输出:

1
2
3
4
5
6
7
8
server posted rdma read req
rdma read completion
server received read complete
server ping data: rdma-ping-5868: KLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
server posted go ahead
send completion
recv completion
Received rkey 101f addr 5645934421e0 len 64 from peer

客户端输出

1
2
3
4
send completion
recv completion
ping data: rdma-ping-5868: KLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy
RDMA addr 56459344f390 rkey 11f5 len 64

▸ 为什么推荐先跑 rping?
rping 使用 RDMA-CM(RoCE v2 下走 UDP/4791),若能互通,说明 GID/寻址/控制面均已就绪。

  1. perftest 验证
1
2
3
4
5
# 服务端(rxe0@vA)
sudo ib_write_bw -d rxe0 -x 1 -R -F -m 1024 -s 1024 -p 19999
# 客户端(rxe1@vB,指向 10.10.0.1)
sudo ib_write_bw -d rxe1 -x 1 -R -F -m 1024 -s 1024 -p 19999 10.10.0.1

▸ perftest 是什么?
perftest 是基于 verbs 的带宽/时延微基准工具集,常用于功能与性能验证。

服务端输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

************************************
* Waiting for client to connect... *
************************************
---------------------------------------------------------------------------------------
RDMA_Write BW Test
Dual-port : OFF Device : rxe0
Number of qps : 1 Transport type : IB
Connection type : RC Using SRQ : OFF
PCIe relax order: ON Lock-free : OFF
ibv_wr* API : OFF Using DDP : OFF
CQ Moderation : 100
Mtu : 1024[B]
Link type : Ethernet
GID index : 1
Max inline data : 0[B]
rdma_cm QPs : ON
Data ex. method : rdma_cm
---------------------------------------------------------------------------------------
Waiting for client rdma_cm QP to connect
Please run the same command with the IB/RoCE interface IP
---------------------------------------------------------------------------------------
local address: LID 0000 QPN 0x0020 PSN 0xeb02b8
GID: 00:00:00:00:00:00:00:00:00:00:255:255:10:10:00:01
remote address: LID 0000 QPN 0x001f PSN 0xe6da3e
GID: 00:00:00:00:00:00:00:00:00:00:255:255:10:10:00:01
---------------------------------------------------------------------------------------
#bytes #iterations BW peak[MiB/sec] BW average[MiB/sec] MsgRate[Mpps]
1024 5000 416.70 409.83 0.419671
---------------------------------------------------------------------------------------

客户端输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---------------------------------------------------------------------------------------
RDMA_Write BW Test
Dual-port : OFF Device : rxe1
Number of qps : 1 Transport type : IB
Connection type : RC Using SRQ : OFF
PCIe relax order: ON Lock-free : OFF
ibv_wr* API : OFF Using DDP : OFF
TX depth : 128
CQ Moderation : 100
Mtu : 1024[B]
Link type : Ethernet
GID index : 1
Max inline data : 0[B]
rdma_cm QPs : ON
Data ex. method : rdma_cm
---------------------------------------------------------------------------------------
local address: LID 0000 QPN 0x001f PSN 0xe6da3e
GID: 00:00:00:00:00:00:00:00:00:00:255:255:10:10:00:01
remote address: LID 0000 QPN 0x0020 PSN 0xeb02b8
GID: 00:00:00:00:00:00:00:00:00:00:255:255:10:10:00:01
---------------------------------------------------------------------------------------
#bytes #iterations BW peak[MiB/sec] BW average[MiB/sec] MsgRate[Mpps]
1024 5000 416.70 409.83 0.419671
---------------------------------------------------------------------------------------

参数方面:
-d rxe0: 使用名为 rxe0 的 RDMA 设备。rxe0 是 Soft-RoCE (RXE) 的软件模拟设备,表明这是在用软件模拟的 RDMA 环境(通常 over Ethernet)。
-R: 使用 RDMA CM 进行连接建立和数据交换。RDMA CM 是一个用于建立连接的抽象层,比传统的 IB 动词更灵活,尤其适用于 RoCE 和跨子网通信。
-F: 在服务器端启动后永远等待客户端连接。如果没有这个参数,服务器可能在一段时间无连接后自动退出。
-m 1024: 设置每次轮询完成队列 (CQ) 前要执行的测试迭代次数为 1024。这是一个与内部流水线优化相关的参数,会影响性能表现。
-s 1024: 设置每次 RDMA 写操作传输的消息大小为 1024 字节。
-p 19999: 指定服务器监听连接的 TCP 端口号 为 19999。客户端需要通过这个端口来连接。

输出结果中,测试在两台通过以太网(Soft-RoCE,即 RXE)连接的虚拟机之间进行,使用 1024 字节的消息大小。测试结果显示,平均带宽达到 409.83 MiB/s(约 3.2 Gbps),这表明 Soft-RoCE 在虚拟环境下的基本功能正常。

错误路径 & 意外处理

  • ping 不通但 rping 能通ICMP 被规则屏蔽或 ARP 未解析(而 CM 的 UDP/4791 未被拦):
1
2
3
sudo nft flush ruleset;
sudo sysctl -w net.ipv4.icmp_echo_ignore_all=0;
arping -I vA 10.10.0.2 / arping -I vB 10.10.0.1
  • perftest 报 **Failed to modify QP … to RTR / Unable to Connect …**,检查两端 GID/设备/地址没对齐或启动顺序错误:
  1. 核对 ibv_devinfo -d rxe{0,1} -v 中的 GID[1] 分别为 ::ffff:10.10.0.1/2;
  2. 先启动服务端,再启动客户端;
  3. 考虑必要时将 MTU降档(如 -m 512 -s 256),稳定后再拉高。
作者

devillove084

发布于

2025-09-19

更新于

2025-09-21

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×