
先说下背景。做网络或者存储的应该都有这种感觉RoCERDMA over Converged Ethernet这几年几乎成了高性能计算和分布式存储的标配协议但凡涉及多节点数据传输、NVMe over Fabric、GPU 通信这类场景都绕不开“roce网络”这几个字。但真要去学它碰到第一堵墙往往不是概念而是硬件——一块支持 RoCE 的 RDMA 网卡动辄上千普通办公机和测试服务器上根本没有连一个能练命令的环境都搭不出来。Soft-RoCE 就是来解决这堵墙的。它是 Linux 内核里一套纯软件实现的 RoCE 协议栈内核模块名是rdma_rxe不需要任何特殊硬件用普通以太网卡甚至 loopback 接口就能创建一个完整的 RDMA 设备。你可以在这个设备上跑rdma、ibv_devinfo、rping、perftest这些工具也能让 RDMA 应用真正建立连接、收发数据。这篇文章是我基于 Soft-RoCE 从零搭建模拟环境、跑通常用命令、再到排错的一手记录适合没有 RoCE 硬件、又想真正上手 RDMA 命令和流程的运维、存储工程师也适合刚接触 RDMA 的初学者照着一步步复现。1. 先弄清楚 Soft-RoCE 在 Linux 里到底做了什么在动手敲命令之前我建议所有准备搭 Soft-RoCE 的人先花十分钟理解一下它的实现方式。因为你如果只把它当成“一块假网卡”去看后面遇到各种报错时很容易摸不着头脑反过来理解了它的设计排查问题时思路会清晰很多。1.1 软 RoCE 和硬件 RoCE 的差异硬件 RoCE 的工作方式是一张网卡内部有专门的 RDMA 引擎负责处理队列对QP、完成队列CQ、内存注册这些逻辑CPU 只需要把工作请求交给网卡剩下的数据搬运和协议封装都在卡上完成。所以硬卡能做到 100Gbps 线速、微秒级时延CPU 占用极低。Soft-RoCE 则完全反过来它把 RDMA 协议栈用软件实现在内核里模块位于drivers/infiniband/sw/rxe对上暴露的接口和硬卡完全一致——同样是/dev/infiniband/uverbs0、/dev/rdma_cm这些设备节点同样是 InfiniBand Verbs 接口。你用户态用的librdmacm、libibverbs根本感知不到底层是硬卡还是软卡这也是为什么用命令练手时体验和真机几乎一样。1.2 报文是怎么封装的RoCE v2 本质上是 UDP 包要理解 Soft-RoCE关键点在于 RoCE 协议本身有 v1 和 v2 两个版本RoCE v1直接封装在以太网二层帧里以太网类型是0x8915只能在同一个二层网络里通信。RoCE v2把 RDMA 报文封装进 UDP/IP 里目的端口固定是4791可以跨越三层路由转发。rdma_rxe实现的是 RoCE v2。它绑定到一个普通网卡比如eth0之后RDMA 连接的管理报文和数据报文都会被包装成 UDP 包从绑定的那个 netdev 发出去。这就解释了为什么软 RoCE 能跑在普通网卡上——它本质上是把 RDMA 内容装在 UDP 里传输。从抓包角度看tcpdump抓到udp port 4791的包就是 RoCE v2 流量。打个比方硬件 RoCE 像是用一条专线把所有货物直接运到目的地而 Soft-RoCE 是把货物装进普通快递包裹里走公共物流。协议栈都是完整的但速度和效率完全不在一个量级。1.3 能做什么、不能做什么提前有预期才不会浪费时间我见过不少人把 Soft-RoCE 当成万能模拟器跑完发现性能惨不忍睹就开骂。这里先把边界划清楚适用场景说明命令练习rdma、ibv_devinfo、perftest、rping等工具的用法和真卡完全一样业务流程验证自己的应用调用 RDMA Verbs 建连、传输数据可以先在软 RoCE 上跑通协议学习配合抓包看 RoCE v2 报文封装、看 GID、看 QP 状态机非常直观CI/CD 功能测试不需要硬卡也能在测试流水线里跑 RDMA 相关用例不适合场景原因性能基准测试软栈全走 CPU带宽和时延都远不如硬卡生产环境承载流量没有硬件卸载CPU 会被打满验证 PFC/ECN 流控这些依赖网卡和交换机能力软 RoCE 根本没有实现简单说Soft-RoCE 的价值是“能让你把一套 RDMA 命令和流程练熟”不是“能让你测出真实性能”。把预期摆正后面每一步都会顺畅很多。2. 动手前的四项检查内核、工具、网卡、设备节点很多人搭建失败不是命令敲错了而是前置条件没满足。我把整个环境准备分成四件事按顺序检查一遍后面基本一次就能建起来。2.1 内核有没有 rdma_rxe 模块首先是内核必须编译了CONFIG_RDMA_RXE。检查方法很简单modinfo rdma_rxe grep -E CONFIG_RDMA_RXE /boot/config-$(uname -r)如果modinfo显示了模块路径和参数说明当前内核里有这个模块如果报modinfo: ERROR: Module rdma_rxe not found再用第二行命令看内核配置。输出CONFIG_RDMA_RXEm或CONFIG_RDMA_RXEy没问题可以用。输出为空或者 No such file当前内核没编译这个模块。以我的经验Ubuntu 20.04/22.04 的发行版内核默认都带了rdma_rxeRocky Linux 9 也带CentOS 7 的默认内核通常不带需要换 elrepo 的 kernel-ml 或者干脆升级系统版本。这个坑我在后面排错章节会详细展开。确认内核支持后先手动加载modprobe rdma_rxe lsmod | grep rdma_rxe这里有一点值得注意早期内核里模块名可能是rxe现在主流发行版都叫rdma_rxe。如果你在旧文档里看到modprobe rxe的写法在新内核上会失败以modinfo rdma_rxe的结果为准。2.2 把测试工具一次性装齐环境里需要用到的命令分三块rdma命令来自iproute2ibv_devinfo、rping来自rdma-coreib_write_bw这些性能工具来自perftest。Debian/Ubuntu 系一条命令装齐apt install -y iproute2 rdma-core libibverbs-dev libibverbs1 ibverbs-utils perftestCentOS/Rocky 系dnf install -y iproute rdma-core libibverbs-utils perftest装完可以验证一下rdma link show ibv_devinfo -v which rping ib_write_bwrdma命令如果没有大概率是iproute2版本太老rping如果没有检查rdma-core是否装上了。Ubuntu 的rping通常在/usr/bin/rping可直接执行。2.3 选一张合适的网卡来绑定Soft-RoCE 是通过绑定一个 netdev 工作的这个 netdev 可以是物理网卡也可以是lo回环接口。两种选择对应不同目标只想在单机练命令、跑通 RDMA 连接直接绑定lo最简单不受物理网络干扰。我建议新手第一次练习都用这种方式。想模拟双机 RoCE 互通绑定物理网卡两个节点都创建 Soft-RoCE 设备并保证底层 IP 能互通。选物理网卡时先看一眼接口名和状态ip link show ip addr show dev eth0确认接口是 UP 状态且有 IP 地址。如果接口被 DPDK、OVS 这类程序接管了绑定 rxe 会失败或者链路状态异常这种情况换一张网卡即可。一个常见误解是“绑定了 rxe 设备之后要给 rxe0 配 IP”。实际上不需要rxe设备直接复用底层 netdev 的 IP 和路由建连时用的是底层接口的地址。这个细节我第一次搭建时也走偏了折腾半天。2.4 确认设备节点和基础资源加载rdma_rxe模块后内核会创建一个 infiniband 子系统。创建 rxe 设备成功后/dev/infiniband/目录下应该出现 uverbs 设备节点ls -l /dev/infiniband/正常会看到类似uverbs0、rdma_cm这样的节点。如果rdma link add成功了但设备节点没出现一般是 udev 规则或权限问题直接重启再试通常能解决。另外 Soft-RoCE 的数据路径完全走 CPUQP、CQ、内存注册都会消耗系统内存。测试机建议至少留 2GB 可用内存如果内存吃紧rping跑起来可能直接报资源不足。操作层面创建 rxe 设备必须要 root 权限普通用户只能跑 perftest 这类用户态工具。3. 创建 rxe0绑定网卡、理解 GID 和自动加载环境检查没问题之后真正的搭建其实只有一条命令。这一章我会把创建过程、参数含义、以及 rxe 设备的工作逻辑一次讲透。3.1 一条命令创建 Soft-RoCE 设备绑定lo接口创建rdma link add rxe_lo type rxe netdev lo rdma link show绑定物理网卡创建rdma link add rxe0 type rxe netdev eth0 rdma link show输出类似link rxe_lo/1 state ACTIVE physical_state LINK_UP netdev lo每个字段含义rxe_lo/1设备名和端口号端口号固定是 1。state ACTIVERDMA 设备状态正常。physical_state LINK_UP物理层状态底层 netdev 是通的。netdev lo说明这个 rxe 设备绑定在哪个网络接口上。如果rdma link add报错先回顾第 2 章的四项检查尤其是内核模块和设备节点。命令本身没有太多花样失败基本都在前置环境。3.2 别给 rxe0 配 IP它复用底层网卡的地址这是我踩过的坑单独拿出来说。很多人习惯了 VLAN、bond 这类虚拟接口的思维觉得创建一个新设备就应该给它配 IP。但 rxe 不是这种模式——它不参与 IP 协议栈它的工作是“把 RDMA 报文封装成 UDP 包交给底层 netdev 发送”所以源 IP、目的 IP、路由这些都是底层 netdev 的事。绑定lo时建连地址用127.0.0.1绑定物理网卡时建连地址用该网卡的 IP。两个节点的 rxe 设备不需要任何额外 IP 配置。3.3 GID 与 RoCE v2 建连的关键RDMA 连接能不能建立很大程度取决于 GID 表是否正确。RoCE 设备会为每个端口维护一张 GID 表连接双方通过 GID 来标识自己。查看当前 rxe 设备的 GIDrdma resource show gid输出示例link rxe_lo/1 gid fe80::1... link rxe_lo/1 gid ::ffff:127.0.0.1rxe 设备绑定 netdev 后会自动根据 netdev 的 IP 地址生成 GID。物理网卡只有 IPv4 地址时会生成 IPv4-mapped 的 GID有 IPv6 地址时会额外生成基于 IPv6 的 GID。因此确保底层网卡有可用的 IP 地址是建连的前提。如果 GID 表是空的rping和perftest都会卡在握手阶段。还有个点值得提RoCE v2 的 UDP 端口固定是 4791这个端口既是 CM 管理报文的端口也是数据报文默认使用的端口。理解这一点后面防火墙排错就有方向了。3.4 重启后自动创建一个 systemd unit如果你只是临时练练命令每次重启手动执行一次rdma link add也行。但如果你想把 Soft-RoCE 作为团队的常备测试环境建议做成开机自启。先在/etc/modules-load.d/rxe.conf里写一行让内核自动加载模块rdma_rxe再建一个 systemd unit 自动创建 rxe 设备。下面以绑定eth0为例[Unit] DescriptionCreate Soft-RoCE rxe0 Afternetwork-online.target Wantsnetwork-online.target [Service] Typeoneshot ExecStart/usr/sbin/rdma link add rxe0 type rxe netdev eth0 RemainAfterExityes [Install] WantedBymulti-user.target保存到/etc/systemd/system/soft-rxe.service后systemctl daemon-reload systemctl enable --now soft-rxe.service需要注意的是Afternetwork-online.target不能少否则系统还没把eth0准备好就执行rdma link add会绑定失败。对大多数用 lo 做实验的人这个 unit 其实没必要直接手动建更灵活。4. 五条命令实测环境从设备信息到真实连接环境建好之后接下来要做的是验证它真的能用。我按从“看信息”到“跑真实连接”的顺序整理了五组命令每一组都有明确的验证目的。4.1 ibv_devinfo 看设备能力ibv_devinfo是判断 RDMA 设备是否可用的第一道关卡ibv_devinfo -d rxe_lo重点看几项hca_id: rxe_lo设备名。fw_ver: 0.0.0软件设备没有固件版本正常。port_state: PORT_ACTIVE端口激活这是最关键的一项。link_layer: EthernetRoCE 的链路层是以太网正常。active_mtu、phys_port_cnt等参数也会显示。如果port_state显示PORT_DOWN说明 rxe 设备和底层 netdev 之间的状态有问题回到第 2 章检查网卡是否 UP。4.2 rdma link 和 rdma resource 查资源rdma命令是 iproute2 家族的一员专门用来查看和管理 RDMA 子系统rdma link show rdma resource show rdma resource show qp rdma resource show gidrdma resource show qp输出里能看到每个 QP 的状态SMI、UD、RC 等和连接上下文。跑测试程序前后各看一次能直观地看到 QP 被创建和销毁这对理解 RDMA 资源模型很有帮助排错时也能发现是否有资源泄漏。4.3 rping 跑通第一次 RDMA CM 连接rping是 rdma-core 自带的测试程序它走的是完整的 RDMA CM 建连流程REQ/REP/ESTABLISHED非常适合用来验证环境能不能建立连接。开两个终端。第一个终端起服务端rping -s -a 127.0.0.1 -p 9999 -C 10 -d rxe_lo第二个终端起客户端rping -c -a 127.0.0.1 -p 9999 -C 10 -d rxe_lo正常会看到服务端和客户端交替打印收发数据的消息最后pingping测试完成。如果卡住不动按第 6 章的排查链路走。4.4 perftest 测量带宽和时延perftest是 RDMA 性能测试的标配工具箱虽然 Soft-RoCE 的数值不能代表真实硬件但用它把带宽和时延测一遍能确认数据通路完全正常。还是开两个终端。服务端ib_write_bw -d rxe_lo --report_gbits客户端ib_write_bw -d rxe_lo 127.0.0.1 --report_gbits跑完之后会输出吞吐量。时延测试用ib_send_lat服务端ib_send_lat -d rxe_lo客户端ib_send_lat -d rxe_lo 127.0.0.1值得留意的是命令中的-d rxe_lo不能省。如果机器上同时有多个 RDMA 设备比如既有软 RoCE 又有硬卡不指定设备时 perftest 默认选系统里的第一个设备很可能会选错。4.5 ibv_rc_pingpong 验证 RC 数据通路ibv_rc_pingpong是另一个非常经典的小工具它建立可靠的连接RC并用一发一收的方式测试数据通路比 rping 更贴近 Verbs 底层。服务端ibv_rc_pingpong -d rxe_lo -p 12345客户端ibv_rc_pingpong -d rxe_lo 127.0.0.1 -p 12345输出会显示两个进程之间来回传输的带宽和时延。只要出现类似scnt1000, swr...的输出并跑完就说明 RC 数据通路完全正常。这五组命令里rping是灵魂——它一旦通了说明从设备创建、GID 表、IP 路由、UDP 封装到 CM 建连这一整条链路都没问题。后面再跑任何业务程序心态上都踏实很多。5. 实测数据与“这个环境到底能练什么”这一章聊聊我在这个环境上测得的数据以及它适合做什么、不适合做什么。我尽量给一个直观的参考值但每个机器的 CPU、内存、虚拟化程度不同数据会有差异重点看数量级。5.1 我跑出来的数据在一台 4 核虚拟机上测试绑定的接口是lo结果如下测试命令类型实测结果ib_write_bw -d rxe_lo --report_gbits单线程写带宽约 2.4 Gbpsib_send_lat -d rxe_lo 127.0.0.1单次发送时延约 23-35 微秒ibv_rc_pingpong -d rxe_lo往返带宽约 1.5 Gbps作为对比一台主流的 ConnectX-6 单端口网卡跑 RoCE v2时延在 1 微秒以内带宽可以到 100Gbps 甚至 200Gbps。数字差距巨大但这正是软 RoCE 的定位——功能完整性能靠 CPU 硬扛。数据路径上的开销来源主要有三块一是每包都要经过内核协议栈完成 UDP/IP 封装和解封装二是软实现里有大量的内存拷贝和状态机处理三是没有硬件卸载CPU 就是数据搬运的主力。所以跑测试时注意观察 CPU 占用会发现一个核直接被打满。5.2 适合在这个环境里练的命令清单虽然性能上不了台面但命令和流程是完全一致的。我建议按下面这个顺序练习设备管理类rdma link show、rdma link add/delete、ibv_devinfo、ibstat。资源查看类rdma resource show qp、rdma resource show cq、rdma resource show gid。基础连接类rping、ibv_rc_pingpong。传输测试类ib_write_bw/lat、ib_read_bw/lat、ib_send_bw/lat。协议观察类配合抓包工具看 RoCE v2 报文。比如绑定lo时执行tcpdump -i lo udp port 4791 -XX然后另开一个终端跑rping能看到完整的 UDP 封装报文。这个练习比看十篇协议文档都管用你能清楚地看到 RDMA 的数据是怎么装进 UDP 的CM 握手有哪些过程。5.3 三条建议别拿软 RoCE 做的事第一别拿它跑真实业务流量更别上生产环境。我之前试过用 Soft-RoCE 挂一个分布式存储的 RDMA 传输模块功能确实能跑起来但多节点并发时 CPU 直接被协议栈打满延迟抖动非常夸张。第二别用它验证流控相关功能。RoCE 在生产环境里依赖 PFC 和 ECN 做无损网络这些特性是网卡和交换机联合实现的Soft-RoCE 没有这部分能力。你在这个环境里测不出任何丢包重传、拥塞控制的效果。第三别拿它做任何官方性能基准测试的数据来源。测试报告里如果用 Soft-RoCE 的数据对比硬卡会被前辈们笑掉大牙。它的定位始终是功能验证和命令练习。6. 高频坑位排查链现象、根因和解决顺序搭建 Soft-RoCE 环境本身不难难的是环境不对劲时怎么一步步定位。这一章我按“现象 - 排查链路 - 解决办法”的方式把最常见的五个问题完整记录下来。6.1 现象modprobe 报找不到 rdma_rxe 模块这是最釜底抽薪的坑尤其在 CentOS 7 和一些最小化安装的发行版上特别常见。报错一般是modprobe: FATAL: Module rdma_rxe not found.排查链路modinfo rdma_rxe grep -E CONFIG_RDMA_RXE /boot/config-$(uname -r)第一条命令看内核是否装了这个模块第二条命令看内核编译选项。如果第二条命令没有任何输出说明内核编译时根本没开CONFIG_RDMA_RXE模块自然不存在。解决办法按优先级排序升级到 Ubuntu 20.04、Rocky Linux 8/9 这类默认开启该选项的发行版CentOS 7 可以安装 elrepo 的 kernel-ml 内核实在不能换系统就自己编译内核并把CONFIG_RDMA_RXEm打开。我一般不推荐自己编译内核投入产出比太低。6.2 现象rdma link add 报 No such file or directory命令本身没问题但创建设备时报错。这个报错的根因通常是用户态和内核态不配套。排查链路ls -l /dev/infiniband/ rdma link show如果/dev/infiniband/是空的或者根本没有这个目录说明内核的 RDMA 核心模块没加载或者 udev 没有创建设备节点。手动加载一下modprobe ib_uverbs modprobe rdma_ucm ls -l /dev/infiniband/另外老内核时代创建 rxe 设备的方式是通过 sysfs 参数文件echo eth0 /sys/module/rdma_rxe/parameters/add如果你的rdma link add一直失败但内核模块能加载可以试试这个老接口。它在新内核上可能已经不存在了但这属于“旧系统救急”的思路具体看你的环境来定。6.3 现象link 状态一直 DOWNport_state 是 PORT_DOWN创建的 rxe 设备能看到但它始终不在 ACTIVE 状态。这时候先确认绑定的是不是一张正常的、有 IP 的网卡ip link show dev eth0 ip addr show dev eth0排查链路确认 ndev 是 UP 状态没有 down。确认该接口没有被 DPDK、OVS 等程序独占。确认该接口不是 VLAN 子接口。rxe 对 VLAN 的支持要看内核版本绑定主接口最省事。用dmesg | grep -i rxe看内核有没有相关信息。我自己遇到过的原因是绑定了一张虽然 UP 但没有分配任何 IP 地址的网卡。RoCE v2 要基于 IP 建连接口连 IP 都没有GID 表就是空的状态自然起不来。给网卡配好 IP 后重新创建 rxe 设备状态立刻变 ACTIVE。6.4 现象rping/perftest 卡住或者连接超时rxe 设备状态正常ibv_devinfo也显示 PORT_ACTIVE但一跑连接测试就卡住最后超时。这个问题的排查链路比较长按顺序走第一步检查连接地址对不对。单机用127.0.0.1双机用对端网卡的实际 IP。最容易被忽视的是 rxe 绑定的网卡和对端之间的路由不通先ping一下对端 IP。第二步检查防火墙。RoCE v2 使用 UDP 4791很多发行版默认防火墙会拦截。临时放行测试iptables -I INPUT -p udp --dport 4791 -j ACCEPT如果用的是 firewalldfirewall-cmd --add-port4791/udp第三步检查 GID 表。执行rdma resource show gid如果 GID 列表是空的说明底层 netdev 没有生成有效的地址条目回到 6.3 检查网卡 IP。第四步换一个测试工具交叉验证。rping卡住时用ibv_rc_pingpong试试如果后者能通说明 CM 流程有问题大概率是 GID 或路由层面的问题如果两者都卡住重点检查防火墙和附网卡状态。6.5 现象rdma resource show qp 里 QP 数量越来越多测试程序异常退出后QP、CQ 资源不会立刻释放这是正常的。但如果你跑了很多次测试发现资源只增不减即使所有测试程序都退出了QP 还挂在那里就要注意了。排查链路rdma resource show qp rdma resource show cq正常情况测试进程退出后资源会被内核回收。如果长时间不回收说明可能有后台进程仍在占用或者内核 rxe 模块的资源回收逻辑异常。等不及的话最干脆的办法是删除设备重建rdma link delete rxe_lo rdma link add rxe_lo type rxe netdev lo或者直接卸载重载模块rmmod rdma_rxe modprobe rdma_rxe这里有个小技巧如果rdma link delete提示设备忙先把占用 rdma 的测试进程全部 kill 掉再执行删除。软 RoCE 的资源管理相比硬卡要简单一些一般重建就能解决。我最早搭这套环境其实是被一个问题逼的局点反馈存储服务在 RoCE 卡上跑异常但手里只有一台普通服务器连 RDMA 网卡长什么样都没见过。后来靠 Soft-RoCE 把整套故障路径在本地复现了一遍才发现问题根本不在 RDMA 协议层而在网关侧的路由策略。那次以后我就建议团队里的新人都先用这个环境把rdma、ibv_*、rping这些命令混熟再上真机。如果你照着上面的步骤也完整跑通了一次rping和ib_write_bw那说明你已经真正理解了一套 RoCE 环境从建链到传数的完整链路这比只背概念文档要扎实得多。