Skip to the content.

RDMA 杂谈

https://www.zhihu.com/column/c_1231181516811390976

HCA 是 Host Channel Adapter。

操作类型

https://zhuanlan.zhihu.com/p/142175657

这个问题非常经典,才发现原来才可以有 READ / WRITE

Memory Region

https://zhuanlan.zhihu.com/p/156975042

你应该怎么理解 MR

可以把 MR 理解成三层约束的组合:

lkey 和 rkey 是什么:

权限的含义: IBV_ACCESS_* 在 libibverbs/verbs.h 里定义,常见的是:

也就是如果没有 lkey rkey ,那么完全无法访问,即便可以访问,也需要有权限的考虑。

对应场景:

如果按常见 RDMA 教学结构,这篇会沿着这条链讲:

  1. 应用有一块普通内存
  2. 调 ibv_reg_mr() 把它注册成 MR
  3. 得到 lkey/rkey
  4. 本地发 WR 时,SGE 里写本地地址和 lkey
  5. 若是 RDMA WRITE/READ,还要写远端地址和 rkey
  6. HCA 校验 key 和权限,合法才执行 DMA

这是 RDMA MR 最标准的认知框架。

最容易混淆的点

  1. malloc() 出来的地址不能直接给 RDMA 用 错。必须先注册成 MR。
  2. 有虚拟地址就够了 错。网卡需要的是注册后的 DMA 映射和 key,不是单纯用户态 VA。
  3. rkey 只是个“句柄” 不完整。它本质上还是访问控制的一部分,不只是索引。
  4. 远端知道地址就能写 错。还需要匹配的 rkey,并且权限允许远程写。

和你现在看内核/rdma-core 的关系

如果把这篇文章和源码对照,你可以这样映射:

Protection Domain : https://zhuanlan.zhihu.com/p/159493100

  1. 为什么已经有 lkey/rkey 了,还要 PD

只有 lkey/rkey 还不够。 文章举的意思是:如果没有 PD,那么只要远端已经和本端某个 QP 建好了连接,理论上它一旦拿到某个 MR 的 VA + rkey,就可能访问那块 MR。 PD 就是在此基 础上再加一层隔离。来源:

所以安全模型变成两层:

也就是说,即使你“知道 key”,但如果 QP 和 MR 不在同一个 PD,硬件仍然会拒绝。

  1. PD 到底在隔离什么

它隔离的不是“网络连通性”,而是“资源组合合法性”。

文章里明确说了:

  1. 这和远端访问有什么关系

PD 是本地概念,但它会影响远端能访问什么。 这是这篇文章最重要的一点:

所以远端能访问到哪块内存,不只是由 rkey 决定,还取决于:

这就是 PD 的真实价值: 把“一个连接能碰到哪些本地资源”限定在一个更小的集合里。

  1. 软件上怎么体现

文章里也讲了软件模型:

这和 rdma-core 的接口是完全一致的:

所以从 API 设计上你就能看到 PD 是“上游父对象”。

  1. 你该怎么用它

这篇文章的建议很实用:

也就是说,PD 不是“越多越对”,而是一个安全与管理粒度的设计选择。

  1. 用一句工程化的话总结

你可以把 PD 理解成:

三者叠加,才构成完整的访问控制。

如果你愿意,我下一步可以直接结合 rdma-core 源码,把:

这三路径里 PD 是怎么一路传到内核和驱动里的,给你串一遍。

Memory Window : https://zhuanlan.zhihu.com/p/353590347

  1. MW 是什么

MW 不是新的内存注册对象来替代 MR,而是在 MR 之上增加一层“可动态授权的远程访问窗口”。

核心目的就是:

所以可以把它理解成:

二级来源明确提到:MW 的用途是“动态地授予和收回已注册缓冲区的远程访问权限”,并且不同 MW 可以绑定到同一个 MR,且权限可不同。来源:

  1. 为什么有 MR 了还要 MW

因为 MR 太“硬”。

如果你只靠 MR 控制远程访问,常见问题是:

MW 解决的是“动态授权”问题。

你可以把它看成:

  1. MW 的关键动作是 bind

文章的核心一定会讲 bind,因为 MW 不是单独工作的。

MW 必须绑定到某个 MR 上,绑定时会指定:

也就是说,MW 本身不拥有内存,它只是把“MR 的一个子范围”以新的授权方式暴露出去。

所以你可以这样理解:

  1. MW 和 rkey 的关系

这里是最容易搞清楚的点。

MW 绑定之后,会产生或使用一个新的 rkey 语义。 远端如果想通过这个 window 访问内存,不是拿原始 MR 的 rkey,而是拿这个 window 当前有效的 rkey。

因此:

这就是它比裸 MR 更灵活的地方: 你可以通过重新 bind / invalidate,改变“当前有效的远程钥匙”。

  1. MW 最重要的能力:撤销快

MW 的真正价值不在“能访问”,而在“能收回”。

如果远端访问授权只靠 MR,那么收回权限通常更重。 如果用 MW,就可以:

所以 MW 非常适合:

  1. 它和 PD/MR/QP 的关系

你前面已经看了 MR 和 PD,这里刚好能串起来:

所以 MW 不是独立于 MR 的体系,而是建立在 MR 之上的控制层。

  1. 用一句工程化的话总结

这篇文章的本质是在讲:

MR 负责“把内存交给 RDMA 系统管理”, MW 负责“把其中某个范围以更灵活、可撤销的方式授权给远端访问”。

如果你只记一个结论,就记这个。

  1. 和 rdma-core/verbs 对应

在 verbs 语义里,这通常对应:

你前面问过 lkey/rkey 和 invalidate_rkey,这和 MW 正好强相关。MW 就是让 rkey 的生命周期管理更灵活。

如果你愿意,我下步可以直接结合 rdma-core 源码,把:

基本内容

PD (Protection Domain) MR (Memory Region) CQ (Completion Queue) QP (Send Queue & Receive Queue)

为什么 rdma 需要这四个模式

RDMA 的内存如何释放问题

› 我想知道,当访问一个远端的内存的时候,如何保证远端的内存被正确的释放,如果远端的用户态进程 crash 了,如何保证 client 依旧可以 WRITE ,如果 client 想要释放内存,server 如何释放,即便 server 的用户态程序 crash 了

[!NOTE] 参考神奇海螺的意见,有待验证

做不到“远端用户态进程 crash 了,但 client 还能继续可靠地写那块原内存,并且最后还能正确释放”这一组要同时成立。

因为 RDMA 远端内存不是独立资源,它依附于远端进程的:

远端进程一旦 crash 或退出,内核会清理这些对象,MR/rkey/QP 最终都会失效。之后 client 不能再合法地继续 WRITE 到原来的那块用户态内存。

先说结论

你要区分两件事:

  1. “client 能不能在 server 用户态死后继续写原 buffer”
  1. “server 用户态死了以后,内存和资源能不能最终正确释放”

所以你的三个目标里:

这三个不能直接靠普通 userspace RDMA 一起满足。

为什么不能

因为远端 RDMA write 依赖两个前提:

而这两者都是远端进程活着时建立的 userspace/verbs 资源。

远端进程 crash 后,内核会做清理:

所以 client 后续再写,最好的情况是失败并得到错误;更糟时如果你设计不当,会遇到连接中断或远端访问错误。

“正确释放远端内存”到底由谁负责

普通模型下,远端内存释放责任在 server 本地:

client 只有“使用权”,没有真正“释放远端内存”的所有权。

所以如果你问:

client 想要释放内存,server 如何释放

标准答案是:

如果 server 用户态 crash 了怎么办

那就别指望通过原用户态协议完成“优雅释放”了。此时只有两种可能:

  1. 内核自动回收
  1. 这块内存本来就不是 server 普通用户进程私有

这已经不是普通“一个 server 进程 malloc+reg_mr”的模型了,而是更复杂的资源托管模型。

如果你真的想让 server crash 后 client 还继续写,怎么做

只能改变资源所有权模型。常见思路有几种。

  1. 独立的内存 owner 进程 不要让业务 server 直接拥有 MR,而是:

这样 client 理论上还能继续写,但前提是:

  1. 共享内存/外部内存池 + 独立注册者 比如:

本质和上面一样,都是把“内存 owner”和“业务逻辑进程”分离。

  1. 内核态/设备态 owner 如果资源由内核驱动、target、或设备侧长期对象持有,那用户态 crash 不一定导致资源立刻消失。 但这已经超出一般 libibverbs userspace buffer 模型了。

推荐的工程做法

如果你是在设计普通 client/server RDMA 协议,正确做法通常不是“server crash 后 client 继续写”,而是:

也就是把它设计成:

如果你想要“client 触发释放,即使 server crash 也最终能释放”

那释放动作不能只依赖 crash 的 server 进程本身。可选办法:

或者更简单:

这通常比“client 精确命令远端 free”更稳。

一句话总结

普通 RDMA 用户态模型下:

如果你愿意,我可以下一步直接给你画三种可落地的生命周期设计:

  1. 普通 client/server MR 模型
  2. 带 lease 的可恢复模型
  3. 独立 memory daemon 的强托管模型

virtio rdma 总结

https://zhuanlan.zhihu.com/p/651023182 : 很好的总结

https://patchew.org/QEMU/20210902130625.25277-1-weijunji@bytedance.com/ : 一个 pr

vmware PVRDMA :

为什么 RoceV2 要把 UDP 和 IP 加进来?

RoCE v1: Ethernet link layer protocol RoCE v2: Internet layer protocol which exists on top of either the UDP/IPv4 or the UDP/IPv6 protocol

RDMA HCA 是什么东西?

The RDMA application speaks to the Host Channel Adapter (HCA) direclty using the RDMA Verbs API. You can see a HCA as a RDMA capable Network Interface Card (NIC). To transport RDMA over a network fabric, InfiniBand, RDMA over Converged Ethernet (RoCE), and iWARP are supported.

https://www.vmware.com/docs/the-basics-of-remote-direct-memory-access-rdma-in-vsphere

开始的

协议的对比

[!NOTE] 参考神奇海螺的意见,有待验证

指标 InfiniBand RoCEv2 差距
端到端延迟 ~100ns ~230ns+ 2.3×+
链路带宽 400-800 Gb/s (NDR) 100-400 Gb/s 领先一代
路由机制 自适应线性路由 标准IP路由 更优负载均衡

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。