本文为达坦科技DatenLord新系列文章【开源周报】的第21篇。
设立这一系列的初衷,是为了更透明地分享达坦科技开源项目的成长轨迹。在这里,我们不仅会同步项目近期的核心开发进展与技术突破,更将通过路线图为您揭示未来的演进方向。
📍 项目地址与参与
GitHub 仓库:https://github.com/open-rdma/open-rdma-driver
我们诚挚邀请所有对高性能网络、Rust系统编程或RDMA技术感兴趣的朋友点击链接关注、支持我们的项目。开源的力量源于社区。您的每一次关注、讨论或代码贡献,都是项目前进的重要动力。期待与您携手,共建更完善的高性能基础设施生态。
01、本周进展
本周主题:围绕 MRC 和 veRoCE 的重传设计,梳理 lossy / multipath RDMA 传输中 packet 级可靠性、乱序接收、SACK/NACK 反馈、timer 兜底和语义完成边界,为后续 open-rdma 的 ACK bitmap 与重传路径设计提供参考。
1. MRC:独立 Reliability 层的重传设计
MRC 的核心是把 packet reliability 从 RDMA transport 语义中拆出来。Reliability SACK/NACK 负责描述 packet 是否到达、是否乱序、是否需要重传;Transport ACK/NAK 负责表达 RDMA transport / semantic 层结果。因此,一个 packet 可以先被 Reliability SACK 确认到达,但后续仍可能因为语义处理失败而被 Transport NAK。
Responder 用 cack\_psn 表示累计确认点,用 receive bitmap 记录累计 ACK 之后的乱序 packet,并通过 max\_psn\_range/MPR 限制 requestor 最多能推进到多远。只要 packet 落在接收窗口内,即使 PSN != ePSN,也可以被接收、记录并做 OOO DDP。
MRC 的重传触发主要有三条路径:
- Reliability NACK:trimmed packet、接收端 bitmap/buffer 资源不足、PSN 超出窗口等明确异常会触发 NACK,requestor 根据 nack\_psn 标记对应 PSN 重传。
- SACK-based loss detection:requestor 根据 cack\_psn、sack\_bitmap、ack\_psn\_offset 和 ooo\_count 判断哪些 hole 可能已经丢失;但 MRC 没有规定具体算法,只要求实现避免 spurious retransmission,并保证同一 packet 最多因 SACK 推断重传一次。
- Local ACK Timeout:如果 ACK/SACK/NACK 丢失或一直没有反馈,requestor 依靠 timer 兜底,超时后重传仍未确认的 packet;超过 retry limit 后 QP 进入 ERROR。
MRC 的重传包保持原 PSN,并设置 BTH.rtx=1。重传不是绕过调度的 fast lane:它仍然受 MPR、congestion window 和 retry counter 限制。这个设计的重点是把“标记需要重传”和“真正允许发出重传包”拆开,避免在接收端窗口或网络拥塞已经紧张时继续扩大问题。
2. veRoCE:贴近 RoCE ACK 体系的选择重传
veRoCE 更接近传统 RoCE ACK 体系,但在编号和反馈上做了扩展。它同时维护 packet-level PSN 和 message-level MSN,并把 request path 与 Read Response/AtomicAck path 分成两套独立 PSN/MSN 空间。普通 request packet 使用 ACK/SACK/NAK,Read Response 和 AtomicAck 使用 ACK\_Rsp/SACK\_Rsp/NAK\_Rsp。
veRoCE 的 receiver 使用 physical Rx bitmap 记录窗口内乱序到达的 packet。ACK 给出累计确认点 aPSN,SACK 在 ACK 基础上附加 128-bit SACKETH.PSN bitmap,用于告诉 sender 哪些乱序 packet 已经到达。这里的 bitmap 是重传和乱序跟踪工具,不是拥塞窗口;真正的拥塞控制由 FCC、CNP/ECN 和 RTT probing 负责。
veRoCE 的快速重传重点在 lazy SACK 和 RxtPSN:
- Receiver 不需要每个乱序包都发 SACK,而是在 OOOD = hPSN - aPSN 超过阈值时发送 SACK。
- Sender 收到 SACK 后,可以认为 aPSN + 1 及其附近未被 bitmap 标记的 packet 可能丢失,并触发 selective retransmission。
- 为避免多个连续 SACK 对同一批 hole 重复重传,veRoCE 推荐使用 RxtPSN 记录上一轮 SACK bitmap 已处理到的最高 PSN;只有 PSN > RxtPSN 的 hole 才进入新一轮快速重传。
- 如果 RxtPSN 长时间不推进,说明前一轮重传本身也可能丢了,可以将 RxtPSN 重置回 aPSN,允许第二轮 selective retransmission。
trimmed packet 则走 Packet Drop NAK:receiver 收到 trimmed packet 后立即发送 NAK,每个 NAK 触发单个 PSN 重传。如果 ACK/SACK/NAK 本身丢失,veRoCE 依靠 Transport Timer 兜底;对 Read Response/AtomicAck,responder 还需要等待 ACK\_Rsp/SACK\_Rsp,超时后重传 response packet。
3. 对 open-rdma 的参考价值
两种设计都没有把 packet-level scoreboard 规定为协议层的固定结构。更准确地说,它们都要求发送侧具备等价的按 PSN 管理能力:能够知道哪些 packet 尚未确认,能根据 ACK/SACK 释放状态,根据 NACK 或 timer 标记重传,并在需要时按原 PSN 重新发送。MRC 规范只明确了 requestor 侧的可靠性状态、timer 和重传约束;veRoCE 则通过 PSN/MSN、PO、SACK bitmap 和 RxtPSN 等机制帮助发送端定位和去重重传。
接收端 bitmap 是乱序接收的核心资源,但它更像 reliability receive window,而不是 congestion window。MRC 通过 MPR 显式反馈接收端可跟踪范围;veRoCE 则依赖 receiver physical bitmap coverage 和 <= 2^23 outstanding 规则。无论采用哪种风格,发送端都需要避免超过接收端可跟踪范围,否则会制造不必要的丢包和 timeout。
ACK/SACK/NACK 丢失也必须作为常态处理。后续 ACK/SACK 的累计确认点可以覆盖早先丢失的反馈;如果一直没有反馈,则 timer 触发重传。receiver 必须正确识别 duplicate packet,不能因为 timeout 重传而重复完成有副作用的语义动作。
从落地顺序看,veRoCE 风格的最小闭环更适合当前阶段:先实现 Rx bitmap + cumulative ACK + selective bitmap + Packet Drop NAK + timer,再考虑 lazy SACK 和 RxtPSN 去重。MRC 的 MPR、Reliability Probe、entropy/path feedback 更适合作为后续多路径增强方向。
02、总结
本周主要围绕 MRC 和 veRoCE 的重传设计 做了横向分析。两者都从传统严格顺序 RC 转向 packet 级乱序接收和选择重传,但设计重心不同:MRC 更强调独立 reliability 控制层、显式 MPR 窗口和路径反馈,适合强 multipath/path-aware 场景;veRoCE 更贴近 RoCE ACK 体系,依靠 ACK/SACK/NAK、lazy SACK、RxtPSN 和 Transport Timer 形成较轻量的重传闭环。对 open-rdma 来说,当前最值得优先吸收的是三点:receiver bitmap 合并在硬件实现上提前、发送侧具备按 PSN 定位和管理重传的能力、ACK/SACK/NACK 丢失时必须依靠 timer 与 duplicate 处理兜底。
达坦科技始终致力于打造高性能AI+Cloud基础设施平台,积极推动AI应用的落地。达坦科技通过软硬件深度融合的方式,提供AI推理引擎和高性能网络,为AI应用提供弹性、便利、经济的基础设施服务,以此满足不同行业客户对AI+Cloud的需求。
公众号:达坦科技DatenLord
DatenLord官网:
知乎账号:
https://www.zhihu.com/org/da-tan-ke-ji
B站:
https://space.bilibili.com/2017027518
邮箱:info@datenlord.com
如果您有兴趣加入达坦科技Rust前沿技术交流群、硬件敏捷开发和验证方法学讨论群或AI Infra 交流群,请添加小助手微信:DatenLord\_Tech
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。