没有 RDMA 网卡,如何写通第一个 RDMA 通信?rdma-core 实战指南 没有 RDMA 网卡如何写通第一个 RDMA 通信rdma-core 实战指南【免费下载链接】rdma-coreRDMA core userspace libraries and daemons项目地址: https://gitcode.com/GitHub_Trending/rd/rdma-core两台机器、万兆网卡TCP 却跑不满带宽、压不进 15 微秒——瓶颈不在网线在内核。rdma-core 是 Linux 内核 InfiniBand 子系统的官方用户态库与守护进程集合让你的进程绕过内核协议栈、直接驱动 RDMA 网卡。本文面向会写 C 和网络编程、但从未写过 RDMA 应用的工程师全程不需要一张真实的 RDMA 卡。先建立一张地图。rdma-core 里与内核设备节点一一对应三套库libibverbs 管/dev/infiniband/uverbsXverbs API核心收发能力librdmacm 管/dev/infiniband/rdma_cm连接管理类似 rdma 版的 socket 建连libibumad 管/dev/infiniband/umadX管理数据报子网管理用。providers/ 目录下则是各内核驱动mlx5、irdma、efa 等的用户态组件编译后自动加载。对新手来说libibverbs 就是主战场其余先记个名字即可。 一条数据通路把 TCP 的概念整体平移到 RDMARDMA 学习最大的劝退点是一堆陌生名词。其实它只是把 TCP 的每个概念换了一张工牌对照一遍就能串起来你熟悉的 TCP 世界RDMA 世界的叫法一句话解释socketQP队列对收发单位含一对 send/recv 队列connect 握手QP 状态机 INIT→RTR→RTS建连即三次ibv_modify_qp改状态malloc 的缓冲区MR注册内存区用ibv_reg_mr向网卡报备send()/recv()ibv_post_send/ibv_post_recv提交的是 Work RequestWRread() 返回CQ完成队列ibv_poll_cq轮询完成通知—PD保护域隔离 MR、QP 等资源的边界心智模型只有一句话应用把 WR 丢进 QP 就走开网卡自己搬数据完成后往 CQ 里丢一个完成项。每字节数据都不经过 CPU这就是零拷贝和内核旁路的全部来源——代价是你要自己管理注册内存和完成队列没有任何人替你兜底。核心五步可以浓缩成几行完整代码见 示例代码目录 里的 rc_pingpong.cctx ibv_open_device(dev); /* 打开设备上下文 */ pd ibv_alloc_pd(ctx); /* 建保护域 */ mr ibv_reg_mr(pd, buf, len, /* 注册内存 */ IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE); qp ibv_create_qp(pd, attr); /* 建 QP后续改状态到 RTS */ rdma-core 最快上手路径三条命令搞定软件 RDMA没有硬件怎么办内核自带软件 providerrdma_rxe用 RoCE 报文模拟和siw基于 TCP 的 iWARP功能与真实网卡一致延迟高但开发调试完全够用。先在任意 Linux 机器上构建仓库git clone https://gitcode.com/GitHub_Trending/rd/rdma-core cd rdma-core bash build.sh ls build/binbuild/bin下会出现ibv_devinfo、ibv_devices、ibv_rc_pingpong等示例程序这是 rdma-core 构建后你最先要认识的几个工具。接着在一台机器上拉起软件设备需较新 iproute2modprobe rdma_rxe rdma link add rxe0 type rxe netdev eth0 ibv_devices预期输出device node GUID ------ ---------- rxe0 02:16:3a:ff:fe:12:34:56两台机器各跑一遍rxe0同时出现在ibv_devices和rdma link输出里说明环境就绪。 跑通第一次通信ibv_rc_pingpongpingpong 是 RC 传输可靠连接类 TCP 语义的最小闭环一端当服务端等待另一端当客户端连接然后循环发收小消息# 机器 A服务端默认监听 TCP 18515 端口 build/bin/ibv_rc_pingpong # 机器 B客户端 build/bin/ibv_rc_pingpong 192.168.1.10客户端预期输出8192000 bytes in 0.62 seconds 106.00 Mbit/sec 1000 iters in 0.62 seconds 621.30 usec/iter注意这个细节TCP 只用来交换一次 QP 的 qpn、lid、gid 等连接信息之后所有数据走 RDMA 的 SEND/RECV 路径。-n控制迭代次数、-s控制消息大小、-e切换成 CQ 事件模式-d、-i指定设备与端口。跑通它你就完整走了一遍发现设备→开上下文→建 QP→改状态→post WR→poll CQ的全流程后面自己写代码只是把这段流程拆开重填。 第一个 RDMA 程序的高频报错排查清单新手卡住的坑高度集中按命中率排序症状真实原因解法ibv_devices为空驱动没加载或软件设备没建modprobe对应驱动或先跑 rxe 那条命令ibv_open_device失败对/dev/infiniband/uverbs0无权限看ls -l /dev/infiniband加 rdma 组或调设备组QP 停在 INITmodify_qp报错RTR 阶段属性没填全用ibv_devinfo -v拿 pkey/lid/gid 逐项补上发送成功但对端没反应忘了ibv_post_recv挂接收 WR收发两端都要保持足够深度的 pending WR数据丢了但没报错没检查完成状态见下方代码永远查wc.status最后一条是最容易翻车的ibv_poll_cq返回的完成项WC可能携带错误状态不检查就默认成功等于埋雷ne ibv_poll_cq(cq, 16, wc); for (i 0; i ne; i) if (wc[i].status ! IBV_WC_SUCCESS) fprintf(stderr, WR failed: %s\n, ibv_wc_status_str(wc[i].status));IBV_WC_WR_FLUSHED基本意味着 QP 已进入错误态RNR则指向对端没挂够接收 WR——报错字符串本身就是最好的定位线索。从 pingpong 到生产三个值得先做的优化吞吐上量后瓶颈首先出现在完成通知上。批量 post一次ibv_post_send提交整链 WR能显著摊薄每次提交开销配合wr_signal只对每 N 个 WR 要完成项可大幅减少 CQ 压力。第二个方向是事件模式ibv_get_cq_eventibv_ack_cq_events取代忙轮询把 CPU 让给别的核pingpong 的-e参数就是现成的参照。第三个方向是资源复用MR 注册本身不便宜生产代码里按大页预注册环形缓冲区避免每请求注册/注销。更深的 API 细节可以翻 libibverbs 文档 按需查阅不必通读。下一步行动清单跑 build.sh打开 build/bin 里的示例拉起 rxe 软件设备ibv_devices 验证两台机器互跑一遍 ibv_rc_pingpong卡住就去 linux-rdma 邮件列表搜坑【免费下载链接】rdma-coreRDMA core userspace libraries and daemons项目地址: https://gitcode.com/GitHub_Trending/rd/rdma-core创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考