RDMA概论
RDMA · 254 字
https://zhuanlan.zhihu.com/p/164908617
DMA与RDMA
DMA
DMA全称为Direct Memory Access,即直接内存访问。意思是外设对内存的读写过程可以不用CPU参与而直接进行。
DMA控制器是专门用来读写内存的设备,将CUP控制的数据复制过程卸载到DAM控制器上。DMA控制器一般是和I/O设备在一起的,也就是说一块网卡中既有负责数据收发的模块,也有DMA模块。
RDMA
RDMA( Remote Direct Memory Access )意为远程直接地址访问,通过RDMA,本端节点可以“直接”访问远端节点的内存。所谓直接,指的是可以像访问本地内存一样,绕过传统以太网复杂的TCP/IP网络协议栈读写远端内存,而这个过程对端是不感知的,而且这个读写过程的大部分工作是由硬件而不是软件完成的。

RDMA可以粗劣的理解为I/O设备直接调用用户空间的DMA,读取用户空间数据。
RDMA优势
- 0拷贝:指的是不需要在用户空间和内核空间中来回复制数据;
- 内核Bypass:指的是IO(数据)流程可以绕过内核,即在用户层就可以把数据准备好并通知硬件准备发送和接收。避免了系统调用和上下文切换的开销。
- CPU卸载:指的是可以在远端节点CPU不参与通信的情况下(当然要持有访问远端某段内存的“钥匙”才行)对内存进行读写,这实际上是把报文封装和解析放到硬件中做了。而传统的以太网通信,双方CPU都必须参与各层报文的解析,如果数据量大且交互频繁,对CPU来讲将是一笔不小的开销,而这些被占用的CPU计算资源本可以做一些更有价值的工作。
传统以太网(Socket)与RDMA技术的通信
https://zhuanlan.zhihu.com/p/139548242
一次基于传统以太网的通信过程


基于RDMA的通信过程


RDMA基本元素
| 缩略语 | 全程 |
|---|---|
| WQ | Work Queue |
| WQE | Work Queue Entry/Element |
| QP | Queue Pair |
| SQ | Send Queue |
| EQ | Receive Queue |
| SRQ | Shared Receive Queue |
| CQ | Completion Queue |
| CQE | Completion Queue Entry/Element |
| WR | Work Request |
| WC | Work Completion |
flowchart LR
subgraph WQ
A[WQE ... ]
end
WQ --> QP
subgraph QP
direction TB
SQ --> EQ
EQ --> SQ
end
subgraph CQ
B[CQE ...]
end
RDMA基本操作类型
Send&Recv – 双端操作(完成一次通信过程需要两端CPU的参与)
Write&Read
首先需要获取对端的可用内存区域和“钥匙”,通常使用Send&Recv操作完成
都是不需要经过对端CPU参与的操作,直接对远端的内存区域进行读写
“读”这个动作所请求的数据,是在对端回复的报文中携带的
RDMA基本服务类型
RDMA中的服务类型:基于QP的通信模型,IB协议中通过“可靠”和“连接”两个维度描述一种服务类型。
flowchart LR
subgraph 连接与数据报
direction LR
B[连接与数据报] --> C[连接:两个QP建立唯一链接,一定到达对端]
B[连接与数据报] --> D[数据报:一个QP发送的WQE可以到达任意对端]
end
subgraph 可靠性
direction LR
A[可靠] --> 应答机制
A --> 数据校验机制
A --> 保序机制
end
| 可靠(Reliable) | 不可靠(Unreliable) | |
|---|---|---|
| 连接(Connection) | RC | UC |
| 数据报(Datagram) | RD | UD |
Memory Region
又称为MR,指的是由RDMA软件层在内存中规划出的一片区域,用于存放收发的数据。IB协议中,用户在申请完用于存放数据的内存区域之后,都需要通过调用IB框架提供的API注册MR,才能让RDMA网卡访问这片内存区域。实际上就是圈出来的一块内存地址。
通常称RDMA硬件为HCA(Host Channel Adapter, 宿主通道适配器),IB协议中对其的定义是“处理器和I/O单元中能够产生和消耗数据包的IB设备”。
MR的用途
- 完成虚拟地址到物理地址的转化(VA --> RA):硬件会在内存中创建并填写一个VA to PA的映射表
- 控制HCA的访问内存权限:注册时产生L_KEY和R_KEY,用于校验合法性
- 避免换页:MR这块内存区域会长期存在于物理内存中不被换页,直到完成通信之后,用户主动注销这片MR。
Protection Domain
又称为PD,意味保护域,将QP和一块内存区域划在一起做隔离。IB协议中规定:每个节点都至少要有一个PD,每个QP都必须属于一个PD,每个MR也必须属于一个PD。 且PD的概念只存在于本端节点中。
Address Handle
GID:IB协议中的节点标识符(类似于IP协议中的IP地址),是一个128bits的序列
AD(Address Handle)是一个指针,指向“地址簿”区域,用于取出某一个节点的地址信息。每次进行UD服务类型的通信之前,用户都需要先通过IB框架提供的接口,来为每一个可能的对端节点创建一个AH,然后这些AH会被驱动放到一个“安全”的区域,并返回一个索引(指针/句柄)给用户。
作用:
- 保证目的地址可用,提高效率
- 向用户隐藏底层地址细节
- 可以使用PD对目的地址进行管理
Queue Pair
- 硬件上,QP是一段包含着若干个WQE的存储空间,IB网卡会从这段空间中读取WQE的内容,并按照用户的期望去内存中存取数据。至于这个存储空间是内存空间还是IB网卡的片内存储空间,IB协议并未做出限制,每个厂商有各自的实现
- 软件上,QP是一个由IB网卡的驱动程序所维护的数据结构,其中包含QP的地址指针以及一些相关的软件属性。
QPC
即Queue Pair Context,用于存储QP相关属性,主要是用于告知硬件QP的相关信息,而软件通过设计数据结构来得知QP信息。
特殊的QPN(Queue Pair Number)
QP0
编号为0的QP用于子网管理接口SMI(Subnet Management Interface),用于管理子网中的全部节点,说实话我也还没搞清楚这个接口的作用,暂且按下不表。
QP1
编号为1的QP用于通用服务接口GSI(General Service Interface),GSI是一组管理服务,其中最出名的就是CM(Communication Management),是一种在通信双方节点正式建立连接之前用来交换必须信息的一种方式。其细节将在后面的文章中专门展开介绍。
QP状态机

RST(Reset)
复位状态。当一个QP通过Create QP创建好之后就处于这个状态,相关的资源都已经申请好了,但是这个QP目前什么都做不了,其无法接收用户下发的WQE,也无法接受对端某个QP的消息。
INIT(Initialized)
已初始化状态。这个状态下,用户可以通过Post Receive给这个QP下发Receive WR,但是接收到的消息并不会被处理,会被静默丢弃;如果用户下发了一个Post Send的WR,则会报错。
RTR(Ready to Receive)
准备接收状态。在INIT状态的基础上,RQ可以正常工作,即对于接收到的消息,可以按照其中WQE的指示搬移数据到指定内存位置。此状态下SQ仍然不能工作。
RTS(Ready to Send)
准备发送状态。在RTR基础上,SQ可以正常工作,即用户可以进行Post Send,并且硬件也会根据SQ的内容将数据发送出去。进入该状态前,QP必须已于对端建立好链接。
SQD(Send Queue Drain)
SQ排空状态。顾名思义,该状态会将SQ队列中现存的未处理的WQE全部处理掉,这个时候用户还可以下发新的WQE下来,但是这些WQE要等到旧的WQE全处理之后才会被处理。
SQEr(Send Queue Error)
SQ错误状态。当某个Send WR发生完成错误(即硬件通过CQE告知驱动发生的错误)时,会导致QP进入此状态。
ERR(Error)
即错误状态。其他状态如果发生了错误,都可能进入该状态。Error状态时,QP会停止处理WQE,已经处理到一半的WQE也会停止。上层需要在修复错误后再将QP重新切换到RST的初始状态。
Completion Queue
产生时机
- RC
- Send:sendMessage -> Server接收数据 -> Server CQE -> ACK -> Client CQE
- Recv: 同Send
- Write:对端CPU不感知,因此只会在ACK后本端产生CQE
- Read:同Write
- UD
只支持Send-Recv操作

https://zhuanlan.zhihu.com/p/259650980
Shared Receive Queue
共享接收队列,是为了节约接收端资源而设计的。将一个RQ共享给多个SQ使用,这是由于SQ中任务的数量要远远超过向RQ中任务的数量,其原因如下:SEND/WRITE/READ都需要通信发起方向SQ中下发一个WR,而只有和SEND配合的RECV操作才需要通信响应方下发WR到RQ中(带立即数的Write操作也会消耗Receive WR,我们还没讲到)。而我们又知道,SEND-RECV这一对操作通常都是用于传递控制信息,WRITE和READ才是进行大量远端内存读写操作时的主角,所以自然SQ的使用率是远远高于RQ的。
SRQ Limit
SRQ可以设置一个水线/阈值,当队列中剩余的WQE数量小于水线时,这个SRQ会就上报一个异步事件。提醒用户“队列中的WQE快用完了,请下发更多WQE以防没有地方接收新的数据”。这个水线/阈值就被称为SRQ Limit,这个上报的事件就被称为SRQ Limit Reached。
https://zhuanlan.zhihu.com/p/279904125
Memory Window
https://zhuanlan.zhihu.com/p/353590347
RDMA优势
- 本地内存零复制,即省去了数据在主机内存的用户空间和内核空间之间复制的步骤,降低了整个数据收发过程的时延。
- 内核旁路( bypass),即数据通路绕过内核,避免了系统调用和上下文切换的时间开销。
- 把数据包的封装和解析工作交由网卡来实现,降低了 CPU 负载。
