注:本文为 “RDMA” 相关文章合辑。
英文引文机翻未校。
图片清晰度受引文所限。
Introduction to Remote Direct Memory Access (RDMA)
Written by: Dotan Barak on March 31, 2014.on February 13, 2015.
What is RDMA?
什么是 RDMA?
Direct memory access (DMA) is an ability of a device to access host memory directly, without the intervention of the CPU(s).
直接内存访问 (DMA) 是设备在没有 CPU 干预的情况下直接访问主机内存的能力。
RDMA (Remote DMA) is the ability of accessing (i.e. reading from or writing to) memory on a remote machine without interrupting the processing of the CPU(s) on that system.
RDMA(远程 DMA)是指在不中断该系统上 CPU 的处理的情况下访问(即读取或写入)远程计算机上的内存的能力。
So? why is this so good?
为什么这么好?
Using RDMA has the following major advantages:
使用 RDMA 具有以下主要优势:
-
Zero-copy - applications can perform data transfer without the network software stack involvement and data is being send received directly to the buffers without being copied between the network layers.
零拷贝 - 应用程序可以在没有网络软件堆栈参与的情况下执行数据传输,并且数据被直接发送到缓冲区,而无需在网络层之间复制。
-
Kernel bypass - applications can perform data transfer directly from userspace without the need to perform context switches.
内核旁路 - 应用程序可以直接从用户空间执行数据传输,而无需执行上下文切换。
-
No CPU involvement - applications can access remote memory without consuming any CPU in the remote machine. The remote memory machine will be read without any intervention of remote process (or processor). The caches in the remote CPU(s) won’t be filled with the accessed memory content.
不涉及 CPU - 应用程序可以访问远程内存,而无需消耗远程计算机中的任何 CPU。远程内存机将在没有远程进程(或处理器)的任何干预的情况下被读取。远程 CPU 中的缓存不会被访问的内存内容填充。
-
Message based transactions - the data is handled as discrete messages and not as a stream, which eliminates the need of the application to separate the stream into different messages/transactions.
基于消息的事务 - 数据作为离散消息而不是流处理,这样应用程序就无需将流分离为不同的消息/事务。
-
Scatter/gather entries support - RDMA supports natively working with multiple scatter/gather entries i.e. reading multiple memory buffers and sending them as one stream or getting one stream and writing it to multiple memory buffers
Scatter/gather entries 支持 - RDMA 支持本地处理多个 scatter/gather 条目,即读取多个内存缓冲区并将它们作为一个流发送,或获取一个流并将其写入多个内存缓冲区
Where can I find RDMA?
在哪里可以找到 RDMA?
You can find RDMA in industries that need at least one the following:
可以在至少需要以下一项的行业中找到 RDMA:
-
Low latency - For example: HPC, financial services, web 2.0
低延迟 - 例如:HPC、金融服务、Web 2.0
-
High Bandwidth - For example: HPC, medical appliances, storage and backup systems, cloud computing
高带宽 - 例如:HPC、医疗设备、存储和备份系统、云计算
-
Small CPU footprint - For example: HPC, cloud computing
CPU 占用空间小 - 例如:HPC、云计算
And in many-many more other industries…
在许多其他行业…
Which network protocols support RDMA?
哪些网络协议支持 RDMA?
Today, there are several network protocols which support RDMA:
目前,有几种支持 RDMA 的网络协议:
-
InfiniBand (IB)- a new generation network protocol which supports RDMA natively from the beginning. Since this is a new network technology, it requires NICs and switches which supports this technology.
InfiniBand (IB) - 新一代网络协议,从一开始就原生支持 RDMA。由于这是一项新的网络技术,因此需要支持该技术的 NIC 和交换机。
-
RDMA Over Converged Ethernet (RoCE)- a network protocol which allows performing RDMA over Ethernet network. Its lower network headers are Ethernet headers and its upper network headers (including the data) are InfiniBand headers. This allows using RDMA over standard Ethernet infrastructure (switches). Only the NICs should be special and support RoCE.
RDMA Over Converged Ethernet (RoCE) - 一种允许通过以太网网络执行 RDMA 的网络协议。它的下部网络头是以太网头,上部网络头(包括数据)是 InfiniBand 头。这允许在标准以太网基础设施(交换机)上使用 RDMA。只有 NIC 应该是特殊的并支持 RoCE。
-
Internet Wide Area RDMA Protocol (iWARP)- a network protocol which allows performing RDMA over TCP. There are features that exist in IB and RoCE and aren’t supported in iWARP. This allows using RDMA over standard Ethernet infrastructure (switches). Only the NICs should be special and support iWARP (if CPU offloads are used) otherwise, all iWARP stacks can be implemented in SW and loosing most of the RDMA performance advantages.
Internet 广域 RDMA 协议 (iWARP) - 一种允许通过 TCP 执行 RDMA 的网络协议。有些功能存在于 IB 和 RoCE 中,但在 iWARP 中不受支持。这允许在标准以太网基础设施(交换机)上使用 RDMA。只有 NIC 应该是特殊的并支持 iWARP(如果使用 CPU 卸载),否则,所有 iWARP 堆栈都可以在软件中实现,从而失去大部分 RDMA 性能优势。
Does it mean that I need to learn several programming APIs?
这是否意味着我需要学习几个编程 API?
No. Luckily, the same API (i.e. verbs) can be used for all the above-mentioned RDMA enabled network protocols. In *nix it is libibverbs and kernel verbs and in Windows it is Network Direct (ND).
否。幸运的是,相同的 API(即 verbs)可以用于所有上述启用 RDMA 的网络协议。在 *nix 中,它是 libibverbs 和 kernel verbs,在 Windows 中它是 Network Direct (ND)。
Are those network protocols interoperable? 这些网络协议是否可互操作?
Since those are different network protocols, their packets are completely different and they cannot send/receive messages directly without any router/gateway between them. However, the same code can support all of them. Since all those network protocols support libibverbs, the same binary can be used without even the need to recompile the source code.
由于它们是不同的网络协议,它们的数据包完全不同,并且它们之间没有任何路由器/网关,它们无法直接发送/接收消息。但是,相同的代码可以支持所有这些。由于所有这些网络协议都支持 libibverbs,因此可以使用相同的二进制文件,甚至不需要重新编译源代码。
Do I need to download special packages to use RDMA or is it part of the Operating System?
我是否需要下载特殊软件包才能使用 RDMA,或者它是操作系统的一部分?
For several Operating Systems, RDMA support is embedded within the kernel. For example, Linux which supports RDMA natively and all major Linux distributions support it. Other Operating Systems may need to download a package (such as OFED) to add RDMA support to it.
对于多个操作系统,RDMA 支持嵌入在内核中。例如,原生支持 RDMA 的 Linux 和所有主要的 Linux 发行版都支持它。其他操作系统可能需要下载一个软件包(例如 OFED)才能为其添加 RDMA 支持。
深入浅出全面解析 RDMA
Master.TJ 于 2018-06-04 11:36:54 发布
RDMA (RemoteDirect Memory Access) 技术全称远程直接内存访问,就是为了解决网络传输中客户端与服务器端数据处理的延迟而产生的。它将数据直接从一台计算机的内存传输到另一台计算机,无需双方操作系统的介入。这允许高吞吐、低延迟的网络通信,尤其适合在大规模并行计算机集群中使用。RDMA 通过网络把资料直接传入计算机的内存中,将数据从一个系统快速移动到远程系统内存中,而不对操作系统造成任何影响,这样就不需要用到多少计算机的处理能力。它消除了数据包在用户空间和内核空间复制移动和上下文切换的开销,因而能解放内存带宽和 CPU 周期用于改进应用系统性能。
本次详解我们从三个方面详细介绍 RDMA:RDMA 背景、RDMA 相关工作、RDMA 技术详解。
一、背景介绍
1.1 传统 TCP/IP 通信模式
传统的 TCP/IP 网络通信,数据需要通过用户空间发送到远程机器的用户空间。数据发送方需要讲数据从用户应用空间 Buffer 复制到内核空间的 Socket Buffer 中。然后内核空间中添加数据包头,进行数据封装。通过一系列多层网络协议的数据包处理工作,这些协议包括传输控制协议(TCP)、用户数据报协议(UDP)、互联网协议(IP)以及互联网控制消息协议(ICMP)等。数据才被 Push 到 NIC 网卡中的 Buffer 进行网络传输。消息接受方接受从远程机器发送的数据包后,要将数据包从 NIC Buffer 中复制数据到 Socket Buffer。然后经过一些列的多层网络协议进行数据包的解析工作。解析后的数据被复制到相应位置的用户空间 Buffer。这个时候再进行系统上下文切换,用户应用程序才被调用。以上就是传统的 TCP/IP 协议层的工作。
1.2 通信网络定义
计算机网络通信中最重要两个衡量指标主要是指高带宽和低延迟。通信延迟主要是指:处理延迟和网络传输延迟。处理延迟开销指的就是消息在发送和接收阶段的处理时间。网络传输延迟指的就是消息在发送和接收方的网络传输时延。如果网络通信状况很好的情况下,网络基本上可以 达到高带宽和低延迟。
1.3 当今网络现状
当今随着计算机网络的发展。消息通信主要分为两类消息,一类是 Large Messages,在这类消息通信中,网络传输延迟占整个通信中的主导位置。还有一类消息是 Small Messages,在这类消息通信中,消息发送端和接受端的处理开销占整个通信的主导地位。然而在现实计算机网络中的通信场景中,主要是以发送小消息为主。所有说发送消息和接受消息的处理开销占整个通信的主导的地位。具体来说,处理开销指的是 buffer 管理、在不同内存空间中消息复制、以及消息发送完成后的系统中断。
1.4 传统 TCP/IP 存在的问题
传统的 TPC/IP 存在的问题主要是指 I/O bottleneck 瓶颈问题。在高速网络条件下与网络 I/O 相关的处理的高开销限制了可以在机器之间发送的带宽。这里高额开销是数据移动操作和复制操作。具体来讲,主要是传统的 TCP/IP 网络通信是通过内核发送消息。Messaging passing through kernel 这种方式会导致很低的性能和很低的灵活性。其中性能低下的原因主要是由于网络通信通过内核传递,这种通信方式存在的很高的数据移动和数据复制的开销。并且现如今内存带宽性相较如 CPU 带宽和网络带宽有着很大的差异。其中很低的灵活性的原因主要是所有网络通信协议通过内核传递,这种方式很难去支持新的网络协议和新的消息通信协议以及发送和接收接口。
二、相关工作
高性能网络通信历史发展主要有以下四个方面:TCP Offloading Engine(TOE)、User-Net Networking (U-Net)、Virtual interface Architecture(VIA)、Remote Direct Memroy Access (RDMA)。U-Net 是第一个跨过内核网络通信的模式之一。VIA 首次提出了标准化 user-level 的网络通信模式,其次它组合了 U-Net 接口和远程 DMA 设备。RDMA 就是现代化高性能网络通信技术。
2.1 TCP Offloading Engine
在主机通过网络进行通信的过程中,主机处理器需要耗费大量资源进行多层网络协议的数据包处理工作,这些协议包括传输控制协议(TCP)、用户数据报协议(UDP)、互联网协议(IP)以及互联网控制消息协议(ICMP)等。由于 CPU 需要进行繁重的封装网络数据包协议,为了将占用的这部分主机处理器资源解放出来专注于其他应用,人们发明了 TOE(TCP/IP Offloading Engine)技术,将上述主机处理器的工作转移到网卡上。
这种技术需要特定网络接口 - 网卡支持这种 Offloading 操作。这种特定网卡能够支持封装多层网络协议的数据包,这个功能常见于高速以太网接口上,如吉比特以太网(GbE)或 10 吉比特以太网(10GbE)。
2.2 User-Net Networking (U-Net)
U-Net 的设计目标是将协议处理部分移动到用户空间去处理。这种方式避免了用户空间将数据移动和复制到内核空间的开销。它的设计宗旨就是移动整个协议栈到用户空间中去,并且从数据通信路径中彻底删除内核。这种设计带来了高性能的提升和高灵活性的提升。
U-Net 的 virtual NI 为每个进程提供了一种拥有网络接口的错觉,内核接口只涉及到连接步骤。传统上的网络,内核控制整个网络通信,所有的通信都需要通过内核来传递。U-Net 应用程序可以通过 MUX 直接访问网络,应用程序通过 MUX 直接访问内核,而不需要将数据移动和复制到内核空间中去。
三、RDMA 详解
RDMA (Remote Direct Memory Access) 技术全称远程直接内存访问,就是为了解决网络传输中服务器端数据处理的延迟而产生的。
RDMA 主要有以下三个特性:1.Low-Latency 2.Low CPU overhead 3. high bandwidth
3.1 RDMA 简介
Remote:数据通过网络与远程机器间进行数据传输。
Direct:没有内核的参与,有关发送传输的所有内容都卸载到网卡上。
Memory:在用户空间虚拟内存与 RNIC 网卡直接进行数据传输不涉及到系统内核,没有额外的数据移动和复制。
Access:send、receive、read、write、atomic 操作。
3.2 RDMA 基本概念
RDMA 有两种基本操作。
-
Memory verbs: 包括 RDMA read、write 和 atomic 操作。这些操作指定远程地址进行操作并且绕过接收者的 CPU。
-
Messaging verbs: 包括 RDMA send、receive 操作。这些动作涉及的接收方 CPU,发送的数据被写入由接收方的 CPU 先前发布的接受所指定的地址。
RDMA 传输分为可靠和不可靠的,并且可以连接和不连接的(数据报)。凭借可靠的传输,NIC 使用确认来保证消息的按序传送。不可靠的传输不提供这样的保证。然而,像 InfiniBand 这样的现代 RDMA 实现使用了一个无损链路层,它可以防止使用链路层流量控制的基于拥塞的损失 [1],以及使用链路层重传的基于位错误的损失 [8]。因此,不可靠的传输很少会丢弃数据包。
目前的 RDMA 硬件提供一种数据报传输:不可靠的数据报(UD),并且不支持 memory verbs。
3.3 RDMA 三种不同的硬件实现
目前 RDMA 有三种不同的硬件实现。分别是 InfiniBand、iWarp(internet Wide Area RDMA Protocol)、RoCE (RDMA over Converged Ethernet)。
目前,大致有三类 RDMA 网络,分别是 Infiniband、RoCE、iWARP。其中,Infiniband 是一种专为 RDMA 设计的网络,从硬件级别保证可靠传输 , 而 RoCE 和 iWARP 都是基于以太网的 RDMA 技术,支持相应的 verbs 接口,如图 1 所示。从图中不难发现,RoCE 协议存在 RoCEv1 和 RoCEv2 两个版本,主要区别 RoCEv1 是基于以太网链路层实现的 RDMA 协议 (交换机需要支持 PFC 等流控技术,在物理层保证可靠传输),而 RoCEv2 是以太网 TCP/IP 协议中 UDP 层实现。从性能上,很明显 Infiniband 网络最好,但网卡和交换机是价格也很高,然而 RoCEv2 和 iWARP 仅需使用特殊的网卡就可以了,价格也相对便宜很多。
-
Infiniband,支持 RDMA 的新一代网络协议。 由于这是一种新的网络技术,因此需要支持该技术的 NIC 和交换机。
-
RoCE,一个允许在以太网上执行 RDMA 的网络协议。 其较低的网络标头是以太网标头,其较高的网络标头(包括数据)是 InfiniBand 标头。 这支持在标准以太网基础设施(交换机)上使用 RDMA。 只有网卡应该是特殊的,支持 RoCE。
-
iWARP,一个允许在 TCP 上执行 RDMA 的网络协议。 IB 和 RoCE 中存在的功能在 iWARP 中不受支持。 这支持在标准以太网基础设施(交换机)上使用 RDMA。 只有网卡应该是特殊的,并且支持 iWARP(如果使用 CPU 卸载),否则所有 iWARP 堆栈都可以在 SW 中实现,并且丧失了大部分 RDMA 性能优势。
3.4 RDMA 技术
传统上的 RDMA 技术设计内核封装多层网络协议并且涉及内核数据传输。RDMA 通过专有的 RDMA 网卡 RNIC,绕过内核直接从用户空间访问 RDMA enabled NIC 网卡。RDMA 提供一个专有的 Verbs Interface 而不是传统的 TCP/IP Socket Interface。要使用 RDMA 首先要建立从 RDMA 到应用程序内存的数据路径 ,可以通过 RDMA 专有的 Verbs Interface 接口来建立这些数据路径,一旦数据路径建立后,就可以直接访问用户空间 buffer。
3.5 RDMA 整体系统架构图
上诉介绍的是 RDMA 整体框架架构图。从图中可以看出,RDMA 在应用程序用户空间,提供了一系列 verbs interface 接口操作 RDMA 硬件。RDMA 绕过内核直接从用户空间访问 RDMA 网卡 (RNIC)。RNIC 网卡中包括 Cached Page Table Entry,页表就是用来将虚拟页面映射到相应的物理页面。
3.6 RDMA 技术详解
RDMA 的工作过程如下:
-
当一个应用执行 RDMA 读或写请求时,不执行任何数据复制。在不需要任何内核内存参与的条件下,RDMA 请求从运行在用户空间中的应用中发送到本地 NIC ( 网卡)。
-
NIC 读取缓冲的内容,并通过网络传送到远程 NIC。
-
在网络上传输的 RDMA 信息包含目标虚拟地址、内存钥匙和数据本身。请求既可以完全在用户空间中处理 (通过轮询用户级完成排列) ,又或者在应用一直睡眠到请求完成时的情况下通过系统中断处理.RDMA 操作使应用可以从一个远程应用的内存中读数据或向这个内存写数据。
-
目标 NIC 确认内存钥匙,直接将数据写人应用缓存中。用于操作的远程虚拟内存地址包含在 RDMA 信息中。
3.7 RDMA 操作细节
RDMA 提供了基于消息队列的点对点通信,每个应用都可以直接获取自己的消息,无需操作系统和协议栈的介入。
消息服务建立在通信双方本端和远端应用之间创建的 Channel-IO 连接之上。当应用需要通信时,就会创建一条 Channel 连接,每条 Channel 的首尾端点是两对 Queue Pairs(QP)。每对 QP 由 Send Queue(SQ)和 Receive Queue(RQ)构成,这些队列中管理着各种类型的消息。QP 会被映射到应用的虚拟地址空间,使得应用直接通过它访问 RNIC 网卡。除了 QP 描述的两种基本队列之外,RDMA 还提供一种队列 Complete Queue(CQ),CQ 用来知会用户 WQ 上的消息已经被处理完。
RDMA 提供了一套软件传输接口,方便用户创建传输请求 Work Request (WR),WR 中描述了应用希望传输到 Channel 对端的消息内容,WR 通知 QP 中的某个队列 Work Queue (WQ)。在 WQ 中,用户的 WR 被转化为 Work Queue Element(WQE)的格式,等待 RNIC 的异步调度解析,并从 WQE 指向的 Buffer 中拿到真正的消息发送到 Channel 对端。
3.7.1 RDAM 单边操作 (RDMA READ)
READ 和 WRITE 是单边操作,只需要本端明确信息的源和目的地址,远端应用不必感知此次通信,数据的读或写都通过 RDMA 在 RNIC 与应用 Buffer 之间完成,再由远端 RNIC 封装成消息返回到本端。
对于单边操作,以存储网络环境下的存储为例,数据的流程如下:
-
首先 A、B 建立连接,QP 已经创建并且初始化。
-
数据被存档在 B 的 buffer 地址 VB,注意 VB 应该提前注册到 B 的 RNIC (并且它是一个 Memory Region) ,并拿到返回的 local key,相当于 RDMA 操作这块 buffer 的权限。
-
B 把数据地址 VB,key 封装到专用的报文传送到 A,这相当于 B 把数据 buffer 的操作权交给了 A。同时 B 在它的 WQ 中注册进一个 WR,以用于接收数据传输的 A 返回的状态。
-
A 在收到 B 的送过来的数据 VB 和 R_key 后,RNIC 会把它们连同自身存储地址 VA 到封装 RDMA READ 请求,将这个消息请求发送给 B,这个过程 A、B 两端不需要任何软件参与,就可以将 B 的数据存储到 A 的 VA 虚拟地址。
-
A 在存储完成后,会向 B 返回整个数据传输的状态信息。
单边操作传输方式是 RDMA 与传统网络传输的最大不同,只需提供直接访问远程的虚拟地址,无须远程应用的参与其中,这种方式适用于批量数据传输。
3.7.2 RDMA 单边操作 (RDMA WRITE)
对于单边操作,以存储网络环境下的存储为例,数据的流程如下:
-
首先 A、B 建立连接,QP 已经创建并且初始化。
-
数据 remote 目标存储 buffer 地址 VB,注意 VB 应该提前注册到 B 的 RNIC (并且它是一个 Memory Region),并拿到返回的 local key,相当于 RDMA 操作这块 buffer 的权限。
-
B 把数据地址 VB,key 封装到专用的报文传送到 A,这相当于 B 把数据 buffer 的操作权交给了 A。同时 B 在它的 WQ 中注册进一个 WR,以用于接收数据传输的 A 返回的状态。
-
A 在收到 B 的送过来的数据 VB 和 R_key 后,RNIC 会把它们连同自身发送地址 VA 到封装 RDMA WRITE 请求,这个过程 A、B 两端不需要任何软件参与,就可以将 A 的数据发送到 B 的 VB 虚拟地址。
-
A 在发送数据完成后,会向 B 返回整个数据传输的状态信息。
单边操作传输方式是 RDMA 与传统网络传输的最大不同,只需提供直接访问远程的虚拟地址,无须远程应用的参与其中,这种方式适用于批量数据传输。
3.7.3 RDMA 双边操作 (RDMA SEND/RECEIVE)
RDMA 中 SEND/RECEIVE 是双边操作,即必须要远端的应用感知参与才能完成收发。在实际中,SEND/RECEIVE 多用于连接控制类报文,而数据报文多是通过 READ/WRITE 来完成的。
对于双边操作为例,主机 A 向主机 B (下面简称 A、B) 发送数据的流程如下:
-
首先,A 和 B 都要创建并初始化好各自的 QP,CQ
-
A 和 B 分别向自己的 WQ 中注册 WQE,对于 A,WQ=SQ,WQE 描述指向一个等到被发送的数据;对于 B,WQ=RQ,WQE 描述指向一块用于存储数据的 Buffer。
-
A 的 RNIC 异步调度轮到 A 的 WQE,解析到这是一个 SEND 消息,从 Buffer 中直接向 B 发出数据。数据流到达 B 的 RNIC 后,B 的 WQE 被消耗,并把数据直接存储到 WQE 指向的存储位置。
-
AB 通信完成后,A 的 CQ 中会产生一个完成消息 CQE 表示发送完成。与此同时,B 的 CQ 中也会产生一个完成消息表示接收完成。每个 WQ 中 WQE 的处理完成都会产生一个 CQE。
双边操作与传统网络的底层 Buffer Pool 类似,收发双方的参与过程并无差别,区别在零拷贝、Kernel Bypass,实际上对于 RDMA,这是一种复杂的消息传输模式,多用于传输短的控制消息。
RDMA (远程直接内存访问) 原理架构图文详解 + 与传统通信模式对比
fine_rain 于 2019-05-29 22:49:31 发布
1 传统通信模式
使用 TCP/IP 协议的应用程序通常采用应用编程接口:UNIX BSD 的套接字(socket),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用 socket。无论编写客户端程序还是服务端程序,系统都要为每个 TCP 连接都要创建一个 socket 句柄。这样导致了每次传输通信,都要经过 OS 和协议栈的管理,因此不管是 Socket 同步通信还是异步通信,都会存在 CPU 占用过高的现象。
1.1 传统网络通信过程
-
数据发送方需要讲数据从用户应用空间 Buffer 复制到内核空间的 Socket Buffer 中
-
然后 Kernel 空间中添加数据包头,进行数据封装。通过一系列多层网络协议的数据包处理工作
-
数据被 Push 到 NIC 网卡中的 Buffer 进行网络传输
-
消息接受方接受从远程机器发送的数据包后,要将数据包从 NIC buffer 中复制数据到 Socket Buffer
-
然后经过一些列的多层网络协议进行数据包的解析工作
-
解析后的数据被复制到相应位置的用户应用空间 Buffer
-
这个时候再进行系统上下文切换,用户应用程序才被调用
- 可以看出传统的通信模式会导致重复的数据拷贝、上下文切换、CPU 处理 *
2 RDMA 基本原理与优势
2.1 基本原理
RDMA 是一种新的直接内存访问技术,RDMA 让计算机可以直接存取其他计算机的内存,而不需要经过处理器的处理。RDMA 将数据从一个系统快速移动到远程系统的内存中,而不对操作系统造成任何影响。
RDMA:
Remote:数据通过网络与远程机器间进行数据传输
Direct:没有内核的参与,有关发送传输的所有内容都卸载到网卡上
Memory:在用户空间虚拟内存与 RNIC 网卡直接进行数据传输不涉及到系统内核,没有额外的数据移动和复制
Access:send、receive、read、write、atomic 操作
传统的 TCP/IP 通信,发送和接收数据的过程中,都是在源端应用层数据从上向下逐层拷贝封装,目的端从下向上拷贝和解封装,所以比较慢,而且需要 CPU 参与的次数很多。RDMA 通信过程中,发送和接收,读 / 写操作中,都是 RNIC 直接和参与数据传输的已经注册过的内存区域直接进行数据传输,速度快,不需要 CPU 参与,RDMA 网卡接替了 CPU 的工作,节省下来的资源可以进行其它运算和服务。
更直观的对比图图:
可以看到传统的方法需要经过用户态 -> 内核 -> 硬件。
而 RDMA 直接是只经过用户态,数据的存取是通过 RDMA 硬件直接操作内存的。
使用 RDMA 的优势如下:
-
零拷贝 (Zero-copy):应用程序能够直接执行数据传输,在不涉及到网络软件栈的情况下。数据能够被直接发送到缓冲区或者能够直接从缓冲区里接收,而不需要被复制到网络层。
-
内核旁路 (Kernel bypass)- 应用程序可以直接在用户态执行数据传输,不需要在内核态与用户态之间做上下文切换。
-
不需要 CPU 干预 (No CPU involvement)- 应用程序可以访问远程主机内存而不消耗远程主机中的任何 CPU。远程主机内存能够被读取而不需要远程主机上的进程(或 CPU) 参与。远程主机的 CPU 的缓存 (cache) 不会被访问的内存内容所填充。
-
消息基于事务 (Message based transactions)- 数据被处理为离散消息而不是流,消除了应用程序将流切割为不同消息 / 事务的需求。
-
支持分散 / 聚合条目 (Scatter/gather entries support)- RDMA 原生态支持分散 / 聚合。也就是说,读取多个内存缓冲区然后作为一个流发出去或者接收一个流然后写入到多个内存缓冲区里去。
3 RDMA 原理详解
3.1 支持 RDMA 的网络协议
目前支持 RDMA 的网络协议主要有三种
-
InfiniBand (IB)
-
iWARP (RDMA over TCP/IP)
-
RoCE (RDMA over Converged Ethernet)
-
RoCEv1 和 RoCEv2
-
InfiniBand通过以下技术保证网络转发的低时延 ( 亚微秒级 ), 采用 Cut-Through 转发模式,减少转发时延;基于 Credit 的流控机制,保证无丢包;硬件卸载;Buffer 尽可能小,减少报文被缓冲的时延 。
**iWARP (RDMA over TCP/IP)**利用成熟的 IP 网络; 继承 RDMA 的优点;TCP/IP 硬件实现成本高,但如果采用传统 IP 网络的丢包策略对性能影响大 。
RDMA over Converged Ethernet (RoCE) 是一种网络协议,允许应用通过以太网实现远程内存访问。目前 RoCE 有两个协议版本。
RoCE v1 是一种链路层协议,允许在同一个广播域下的任意两台主机直接访问。
RoCE v2 是一种 Internet 层协议,即可以实现路由功能。虽然 RoCE 协议这些好处都是基于融合以太网的特性,但是 RoCE 协议也可以使用在传统以太网网络或者非融合以太网络中。
RoCE 和 InfiniBand,一个定义了如何在以太网上运行 RDMA,而另一个则定义了如何在 IB 网络(主要是基于集群的应用)中运行 RDMA
RoCE 和 iWARP,一个是基于无连接协议 UDP,一个是基于面向连接的协议 (如 TCP)。
- 目前,虽然 IB、以太网 RoCE、以太网 iWARP 这三种 RDMA 技术使用统一的 API,但它们有着不同的物理层和链路层。在以太网解决方案中,RoCE 相对于 iWARP 来说有着明显的优势,这些优势体现在延时、吞吐率和 CPU 负载。RoCE 被很多主流的方案所支持,并且被包含在 Windows 服务软件中 *
3.2 核心概念
RDMA 是
基于消息
的数据传输协议(而不是基于字节流的传输协议),所有数据包的组装都在 RDMA 硬件上完成
的,也就是说 OSI 模型中的下面 4 层 (传输层,网络层,数据链路层,物理层) 都在 RDMA 硬件上完成。
一个名为 OpenFabric Alliance 的组织) 提供了 RDMA 传输的一系列 Verbs API,开发了 OFED (Open Fabric Enterprise Distribution) 协议栈,支持多种 RDMA 传输层协议。
RDMA 应用和 RNIC (RDMA-aware Network Interface Controller) 之间的传输接口层 (Software Transport Interface) 被称为 Verbs 或 RDMA API
RDMA API (Verbs) 主要有两种 Verbs:
-
内存 Verbs (Memory Verbs),也叫 One-SidedRDMA。包括 RDMA Reads, RDMA Writes, RDMA Atomic。这种模式下的 RDMA 访问完全不需要远端机的任何确认。
-
消息 Verbs (Messaging Verbs),也叫 Two-SidedRDMA。包括 RDMA Send, RDMA Receive。这种模式下的 RDMA 访问需要远端机 CPU 的参与。
在实际中, SEND /RECEIVE 多用于连接控制类报文,而数据报文多是通过 READ/WRITE 来完成的 。
3.2.1 基本概念
1、Memory Registration (MR) | 内存注册
创建两个 key (local 和 remote) 指向需要操作的内存区域,注册的 keys 是数据传输请求的一部分。
同时,RDMA 硬件对用来做数据传输的内存是有特殊要求的。
-
在数据传输过程中,应用程序不能修改数据所在的 内存。
-
操作系统不能对数据所在的内存进行 page out 操作 – 物理地址和虚拟地址的映射必须是固定不变的
2、Queues | 队列
RDMA 一共支持三种队列,发送队列 (SQ) 和接收队列 (RQ),完成队列 (CQ)。其中,SQ 和 RQ 通常成对创建,被称为 Queue Pairs (QP)。
*RDMA 是基于消息的传输协议,数据传输都是异步操作。*RDMA 操作其实很简单,可以理解为:
-
Host 提交工作请求 (WR) 到工作队列 (WQ): 工作队列包括发送队列 (SQ) 和接收队列 (CQ)。工作队列的每一个元素叫做 WQE, 也就是 WR。
-
Host 从完成队列 (CQ)中获取工作完成 (WC): 完成队列里的每一个叫做 CQE, 也就是 WC。
-
具有 RDMA 引擎的硬件 (hardware) 就是一个队列元素处理器。 RDMA 硬件不断地从工作队列 (WQ) 中去取工作请求 (WR) 来执行,执行完了就给完成队列 (CQ) 中放置工作完成 (WC)。
从生产者 - 消费者的角度理解就是:
-
Host 生产 WR, 把 WR 放到 WQ 中去
-
RDMA 硬件消费 WR
-
RDMA 硬件生产 WC, 把 WC 放到 CQ 中去
-
Host 消费 WC
3、Send/Recv 操作
SEND/RECEIVE 是双边操作,即需要通信双方的参与,并且 RECEIVE 要先于 SEND 执行,这样对方才能发送数据,当然如果对方不需要发送数据,可以不执行 RECEIVE 操作,因此该过程和传统通信相似,区别在于 RDMA 的零拷贝网络技术和内核旁路,延迟低,多用于传输短的控制消息。
4、read/write 操作
-
RDMA 读操作本质上就是 Pull 操作, 把远程系统内存里的数据拉回到本地系统的内存里。
-
接收方必须提供虚拟地址和目标存储内存的 remote_key。
-
接收方需要初始和接受提醒通知,发送方是完全被动的,并且不会接受任何通知
-
-
RDMA 写操作本质上就是 Push 操作,把本地系统内存里的数据推送到远程系统的内存里。
-
发送方必须提供虚拟地址和目标读取内存的 remote_key。
-
发送方需要初始和接受提醒通知,接受方是完全被动的,并且不会接受任何通知
-
3.2.2 RDMA 工作流程
要使用 RDMA 首先要建立从 RDMA 到应用程序内存的数据路径,可以通过 RDMA 专有的 verbs interface 接口来建立这些数据路径,一旦数据路径建立后,就可以直接访问用户空间 buffer。
RDMA 的工作过程如下:
-
初始化 context,注册内存域
-
建立 RDMA 连接
-
通过 SEND/RECEIVE 操作,C/S 交换包含 RDMA memory region key 的 MSG_MR 消息(一般是客户端先发送)
-
通过 WRITE/READ 操作,进行数据传输(单边操作)
-
发送 MSG_DONE 消息,关闭连接
更细节化的流程描述:
-
消息服务建立在通信双方本端和远端应用之间创建的 Channel-IO 连接之上。当应用需要通信时,就会创建一条 Channel 连接,每条 Channel 的首尾端点是两对 Queue Pairs(QP)。
-
每对 QP 由 Send Queue(SQ)和 Receive Queue(RQ)构成,这些队列中管理着各种类型的消息。QP 会被映射到应用的虚拟地址空间,使得应用直接通过它访问 RNIC 网卡。
-
除了 QP 描述的两种基本队列之外,RDMA 还提供一种队列 Complete Queue(CQ),CQ 用来知会用户 WQ 上的消息已经被处理完。
-
RDMA 提供了一套软件传输接口,方便用户创建传输请求 Work Request (WR),WR 中描述了应用希望传输到 Channel 对端的消息内容,WR 通知 QP 中的某个队列 Work Queue (WQ)。
-
在 WQ 中,用户的 WR 被转化为 Work Queue Element(WQE)的格式,等待 RNIC 的异步调度解析,并从 WQE 指向的 Buffer 中拿到真正的消息发送到 Channel 对端。
RDMA 双边操作(send/receive)
对于双边操作为例,A 向 B 发送数据的流程如下:
-
首先,A 和 B 都要创建并初始化好各自的 QP,CQ
-
A 和 B 分别向自己的 WQ 中注册 WQE,对于 A,WQ=SQ,WQE 描述指向一个等到被发送的数据;对于 B,WQ=RQ,WQE 描述指向一块用于存储数据的 buffer。
-
A 的 RNIC 异步调度轮到 A 的 WQE,解析到这是一个 SEND 消息,从 buffer 中直接向 B 发出数据。数据流到达 B 的 RNIC 后,B 的 WQE 被消耗,并把数据直接存储到 WQE 指向的存储位置。
-
AB 通信完成后,A 的 CQ 中会产生一个完成消息 CQE 表示发送完成。与此同时,B 的 CQ 中也会产生一个完成消息表示接收完成。每个 WQ 中 WQE 的处理完成都会产生一个 CQE。
双边操作与传统网络的底层 buffer pool 类似,收发双方的参与过程并无差别,区别在零拷贝、kernel bypass,实际上传统网络中一些高级的网络 SOC 已经实现类似功能。对于 RDMA,这是一种复杂的消息传输模式,多用于传输短的控制消息。
RDAM 单边操作(read)
READ 和 WRITE 是单边操作,只需要本端明确信息的源和目的地址,远端应用不必感知此次通信。对于操作发起端,数据的读或写都通过在 RNIC 与应用 Buffer 之间完成,再由远端 RNIC 封装成消息返回到本端。
对于单边操作,以 B 对 A 的 read 操作为例,数据的流程如下:
-
首先 A、B 建立连接,QP 已经创建并且初始化。
-
数据被存档在 A 的 buffer 地址 VA,注意 VA 应该提前注册到 A 的 RNIC,并拿到返回的 local key,相当于 RDMA 操作这块 buffer 的权限。
-
A 把数据地址 VA,key 封装到专用的报文传送到 B,这相当于 A 把数据 buffer 的操作权交给了 B。同时 A 在它的 WQ 中注册进一个 WR,以用于接收数据传输的 B 返回的状态。
-
B 在收到 A 的送过来的数据 VA 和 R_key 后,RNIC 会把它们连同存储地址 VB 到封装 RDMA READ,这个过程 A、B 两端不需要任何软件参与,就可以将 A 的数据存储到 B 的 VB 虚拟地址。
-
B 在存储完成后,会向 A 返回整个数据传输的状态信息。
单边操作传输方式是 RDMA 与传统网络传输的最大不同,只需提供直接访问远程的虚拟地址,无须远程应用的参与其中,这种方式适用于批量数据传输。
注:作者水平有限,如有错误欢迎指正
参考链接:
https://blog.csdn.net/cjqxiong/article/details/78814213
https://blog.csdn.net/qq_21125183/article/details/80563463
https://www.cnblogs.com/vlhn/p/7909893.html
https://blog.csdn.net/zjttlance/article/details/80318763
https://www.sohu.com/a/229080366_632967
https://blog.csdn.net/upupday19/article/details/79377984
DMA、链式 DMA、RDMA(精华讲解)
caodongwang 已于 2023-07-25 15:00:59 修改
一、DMA
DMA 全称 Direct Memory Access,即直接存储器访问。CPU 完成传输配置后,即可不在参与传输过程,由 DMA 控制器将数据从一个地址空间复制到另外一个地址空间。最常见的是本地 DMA 传输,如图 1.1 所示。
图 1.1
CPU 设置好三要素(源、目的、大小)后,由 DMA 控制器将内存块 A 的内容拷贝到内存块 B 中。这是普通 DMA 传输,那么,PCIe 设备是如何完成 DMA 传输的呢?
图 1.2
PCIe 设备理想的 DMA 传输过程如图 1.2 所示,主机端(主片)对 PCIe 设备(从片)上 DMA 控制器配置后,由 DMA 控制将主机内存块 A 上数据搬运自身内存块 B 上。这里就有两个疑问了:
-
为什么是 PCIe 设备(从片)上的 DMA 控制器?
-
为什么是主机端(主片)来配置 DMA 控制器?
带着两个问题往下看。实际上 PCIe 总线上 DMA 过程如图 1.3 所示。
图 1.3
真实的数据搬运过程需要透过 IOMMU(ARM 架构为 SMMU)并跨越 PCI 域,才能到达从片内存上。
先回答第一个问题。一般情况主片无法直接访问到从片内存,此外,常出现一主多从情况,为提高资源利用率,也多采用从片 DMA。
我们知道一般 X86 架构在没有开启 IOMMU 前,主片主存储域地址与 PCI 域地址是平行映射的,但开启 IOMMU 后就没有确定的映射关系了。比如,内存块 A 地址为 0x100,平行映射后也是 0x100,但开启 IOMMU 后,映射后的地址可能是 0x900,也可能是 0x200,即没有确定的映射地址。
从片上 DMA 控制器想要把主片内存块 A 上数据搬运到从片内存块 B 上,就需要知道内存块 A 通过 IOMMU 映射后的地址,而这是从片无法知道的,所以一般都是由主片来配置从片 DMA 控制器,这便是第二个问题答案。
我们知道,DMA 控制器所看到的都是物理地址,搬运的数据需要在连续的物理地址上,那么问题来了:如果内存紧张无法申请出连续的物理地址怎么办?
由这个问题引出本文第二部分 —— 链式 DMA!
二、链式 DMA
为了更好讲解链式 DMA 传输过程,以某个 PCIe 的 DMA 过程为例。
主片申请一块 4k 对齐的内存空间存放数据,一般使用 posix_memalign 函数。如图 2.1 所示,可以看见虚拟内存连续,但物理内存离散,只有物理页 D、E 相邻。获取这段虚拟内存对应的物理页,将它们的描述结构保存在 pages 数组中,同时 pin 住这些物理页,避免存放数据的内存被系统换页到硬盘中,导致数据搬运过程中 DMA 控制器读取内存不是用户所预期的。
图 2.1
若虚拟页已映射物理页,则调用 find_vma_intersection、follow_pfn 和 pfn_to_page 函数。若未映射,则调用 get_user_pages_fast 函数。从而获取以用户虚拟地址开始的 5 个虚拟页对应的物理页,将它们的描述结构保存在 pages 数组中。
调用 sg_alloc_table_from_pages 函数,传入上面获取的 pages 数组,即可得到一个 sg_tabel 散列表,即图 2.2 右侧 4 个条目合起来称为 sg_tabel 散列表。
图 2.2
在填充 sg_tabel 散列表时,还会将相邻的物理页合并成一个条目,也就是物理页 D 与物理页 E 合并为条目 DE。sg_table 表对应结构体为:
图 2.3
每个块物理页对应一个条目 scatterlist 结构,其描述结构体为:
图 2.4
也就是说,现在这个 sg_tabel 散列表描述着这些物理页,其中 dma 地址是映射后的 PCI 域上地址,但这里还未得到。
未开启 IOMMU 开启 IOMMU
图 2.5
调用 pci_map_sg 函数完成离散映射,同时填充 sg_table 表中每个条目的 dma 地址,过程如图 2.5 所示,分为两种情况,在未开启 IOMMU 时,映射是平行映射,在开启 IOMMU 后,将会把离散的物理页映射成连续的 PCI 域空间,但并不会改变条目个数。至此 sg_tabel 离散映射表中即可准确描述数据内存在 PCI 域上地址。
图 2.6
如图 2.6 所示(未开启 IOMMU)使用 sg_tabel 散列表填充从片的 DMA 描述子(与从片约定好的格式),也就是图 2.6 中间 task 块,其结构如下:
图 2.7
结构内部包含源地址、目标地址、大小及下一个 task 结构所在地址,就如同链表一样串在一块,所以称为链式 DMA(需硬件支持)。
让从片的 BARx 窗口映射从片特定地址,然后主片通过 ioremap 将 BARX 空间映射到虚拟内存空间,最后将填充好的 DMA 任务描述子拷贝到 BARX 虚拟空间,进而通过 TLP 总线事务传输至从片特定 DDR 地址上,过程如图 2.6 所示。
图 2.8
配置从片的 DMA 控制寄存器,从特定 DDR 地址上拿到 DMA 任务描述列表,即可开始数据搬运,如图 2.8 所示(未开启 IOMMU)。注:从片上内存块依旧是连续物理内存块。
至此,链式 DMA 讲解结束,接下来讲解的是基于 PCI 域上链式 DMA 技术的 RDMA 技术。
三、RDMA
本部分只解释核心名词和概念,尽量简化不必要内容,方便理解。
3.1 RDMA 技术简介
3.1.1 RDMA 优劣势及应用场景
RDMA 是 Remote Direct Memory Access 的缩写,即远程直接数据存取。使用 RDMA 的优势如下:
-
零拷贝 (Zero-copy) - 应用程序能够直接执行数据传输,在不涉及到网络软件栈的情况下。数据能够被直接发送到缓冲区或者能够直接从缓冲区里接收,而不需要被复制到网络层。
-
内核旁路 (Kernel bypass) - 应用程序可以直接在用户态执行数据传输,不需要在内核态与用户态之间做上下文切换。
-
不需要 CPU 干预 (No CPU involvement) - 应用程序可以访问远程主机内存而不消耗远程主机中的任何 CPU。远程主机内存能够被读取而不需要远程主机上的进程(或 CPU) 参与。远程主机的 CPU 的缓存 (cache) 不会被访问的内存内容所填充。
-
消息基于事务 (Message based transactions) - 数据被处理为离散消息而不是流,消除了应用程序将流切割为不同消息 / 事务的需求。
-
支持分散 / 聚合条目 (Scatter/gather entries support) - RDMA 原生态支持分散 / 聚合。也就是说,读取多个内存缓冲区然后作为一个流发出去或者接收一个流然后写入到多个内存缓冲区里去。
既然 RDMA 技术这么好,为什么没能大规模普及?这就不能不说 RDMA 技术的劣势了,主要有两个:
-
网络要求苛刻:RDMA 为了达到高性能低延时的目标,使得 RDMA 对网络有苛刻的要求,就是网络不能丢包,否则性能下降会很大,这对底层网络硬件提出更大的挑战,同时也限制了 rdma 的网络规模;相比而言,tcp 对于网络丢包抖动的容忍度就大很多。
-
成本高:RDMA 通过硬件实现高带宽低时延,降低了 CPU 的负载,但代价是需要特定的硬件,硬件成本较高。软件上,RDMA 技术的应用接口是全新的,大多数现有程序都需要作移植适配及优化,有一定挑战,人工成本高。
目前,RDMA 技术有三个比较好的应用方向,即存储、HPC(高性能计算)及数据中心,简要描述如下:
-
为存储系统和计算系统加速,充分利用高带宽低延迟以及释放 CPU 通信处理。RDMA 通过网络把资料直接传入计算机的存储区,将数据从一个系统快速移动到远程系统存储器中,而不对操作系统造成任何影响,这样就不需要用到多少计算机的处理功能。
-
为 GPU 异构计算通信加速,充分利用 Zero Copy 的特性,减少数据通路中的拷贝次数,大大降低 GPU 之间的传输延迟。
-
数据中心会存在大量的分布式计算集群,但大量并行程序的通讯延迟,则会极大影响整个计算过程的效率。使 RDMA 网络和传统数据中心融合,将会有很好的收益。
3.1.2 RDMA 协议
RDMA 有三种协议,如下图所示:
图 3.0
图 3.0 较为直观的反映三种协议之间差异,再简单介绍一下它们。
Infiniband
2000 年由 IBTA(InfiniBand Trade Association)提出的 IB 协议是当之无愧的核心,其规定了一整套完整的链路层到传输层(非传统 OSI 七层模型的传输层,而是位于其之上)规范,但是其无法兼容现有以太网,除了需要支持 IB 的网卡之外,企业如果想部署的话还要重新购买配套的交换设备。
RoCE
RoCE 从英文全称就可以看出它是基于以太网链路层的协议,v1 版本网络层仍然使用了 IB 规范,而 v2 使用了 UDP+IP 作为网络层,使得数据包也可以被路由。RoCE 可以被认为是 IB 的 “低成本解决方案”,将 IB 的报文封装成以太网包进行收发。由于 RoCE v2 可以使用以太网的交换设备,所以现在在企业中应用也比较多,但是相同场景下相比 IB 性能要有一些损失。
iWARP
iWARP 协议是 IETF 基于 TCP 提出的,但是因为 TCP 是面向连接的协议,而大量的 TCP 连接会耗费很多的内存资源,另外 TCP 复杂的流控等机制会导致性能问题,所以 iWARP 相比基于 UDP 的 RoCE v2 来说并没有优势(IB 的传输层也可以像 TCP 一样保证可靠性),所以 iWARP 相比其他两种协议的应用不是很多。
需要注意的是,上述几种协议都需要专门的硬件(RDMA 网卡)支持。后续内容以 RoCEv2 协议进行讲解,但由于本部分只讲解原理,并不涉及底层实现,因此差异不大。
3.1.3 RDMA 原理简介
用一张图描述 RDMA 过程,如图 3.1 所示
图 3.1
HCA 是宿主通道适配器,即 RDMA 网卡。相比于 TCP/IP 数据传输,RDMA 传输可直接将本端用户态虚拟内存数据传输到对端用户态内存中,而不需要陷入内核!
这是如何实现的?通过本文前两部分讲解,我们知道带 DMA 引擎的 PCI 设备能够直接读写宿主机内存,如下图 3.2 所示。
图 3.2
如果 DMA 引擎从内存块 A 读取的数据不是放到内存块 B,而是通过某种方法传递出去会怎样?如下图 3.3 所示。
图 3.3
原理:
1.HCA 是带 DMA 引擎的 PCI 设备,具有读写主机 DDR 能力。
2.HCA 是特殊网卡,除了普通网卡功能外,内部支持 IB 传输协议。
HCA(RDMA 网卡)读取本端数据后,在内部将数据按某些格式组包,再通过硬件接口传输到对端 HCA 上,由对端 HCA 解包后写入对端内存。值得注意的是,内存块 A、B 都是连续的虚拟内存,对应的物理内存可不一定连续。
HCA 硬件上天然支持 RDMA 传输,但软件上实现可不容易,先看下图。
图 3.4
先简单介绍一下图 3.4 中模块:
libibverbs.so:rdma-core 核心库
libmlx5.so:用户态驱动,也是个动态链接库,实现厂商的驱动逻辑
ib_uverbs.ko:uverbs 驱动
ib_core.ko:RDMA 子系统核心模块
mlx5_ib.ko:RDMA 硬件驱动程序(PCI 设备驱动),负责直接和硬件交互
图 3.4 中有两条路径,为后续描述方便,称右侧路径为准备路径,称左侧路径为工作路径。可以看到,准备路径需要陷入内核态,而工作路径将绕过内核直接操作硬件,后续的讲解将从这两部分说明。上面说到,硬件天然支持 RDMA 传输,而软件的工作简要概括就是,通过某种方法告诉硬件三要素 —— 源、目的、大小。
3.2 准备阶段
准备阶段的部分工作就是获取三要素(源、目的、大小),但在此之前还需解决一个问题,在用户态下,用什么方法绕过内核,直接告诉硬件三要素?
3.2.1 获取通知方法
以 X86 架构为例,我们知道 BOIS 启动阶段会在主机上为每个 PCI 设备分配 BAR 空间,如图 3.5 主存储域上橘黄色块,就是 RDMA 网卡的 BAR 空间。
图 3.5
RDMA 设备驱动(如 mlx5_ib.ko)匹配上设备后,会执行一系列初始化动作,同时保存设备 BAR 空间在主存储域上的地址。
用户空间进程调用 mmap 函数分配一块虚拟内存,同时将调用到 RDMA 设备驱动的 mmap 函数,进而将主存储域上设备 BAR 空间映射到所申请的虚拟内存!所以在用户空间操作 bar 虚拟空间,即可操作 RDMA 网卡的某些寄存器或内存。
在这块虚拟内存中,比较重要的是 Doorbell,其实就是门铃的意思,是一种通知机制,当用户准备好工作请求之后,向 Doorbell 的地址中写一下数据,就等于敲了一下门铃,硬件就知道可以开始干活了。这便是用户态下的通知方法。
3.2.2 获取源
通知方法有了,现在还需获取三要素,先来说源怎么获取,需要说明一下,这个源是一个集合,不仅仅是数据源地址。
图 3.6
如图 3.6 所示,用户申请一块长度为 len 的虚拟内存,执行 RDMA 注册函数,将会得到一个映射表,包含两部分,一个是 sg_table 记录着物理地址到 pci 域地址的转换关系,另一个是 VA->PA 映射表,记录着 VA 到 PA 的转换关系。VA->PA 映射表很容易理解,sg_tabel 获取过程和本文第二部分中描述类似,同样也会 pin 主内存,这里不再赘述。除此之外,还会获得 lkey 和 rkey,一个是本端操作秘钥,另一个是本端赋予远端的操作秘钥。秘钥由两部分组成,低字节部分是真正的钥匙,高字节部分是本 MR 的映射表在缓存区的索引。
每注册一个 MR 都会生成映射表和秘钥,这一系列映射表将放一个硬件知道的缓存区中,由秘钥的高字节索引。
还有一个比较重要的东西,叫 QP 工作队列对,由 SQ 发送队列和 RQ 接收队列组成。QP 是软件向硬件 “发号施令” 的媒介,由用户调用特定函数将其创建,如下图 3.7 所示。
图 3.7
除了创建 QP 外,还会创建 QP 的上下文 QPC,即描述 QP 属性的一个结构,这个结构放在硬件知道的一段缓存区里,由 QP 号(QPN)索引,也就是说,可以有很多个 QP,它们之间由 QPN 区分。值得注意的是,QPC 中有一个 GID 存储区域,这个是存储对端 GID 的(RC 连接)。
GID 是一个全局 ID,由 MAC 地址和 IP 地址转换得来,根据 GID 就可以找到局域中唯一宿主机。调用专用函数可以获取本端的 GID 序列号。
至此,源集合已准备好,有 MR addr、len、lkey、QPN,再看看如何获取目的集合。
3.2.3 获取目的
本端是无法直接获得对端基本信息的,所以需要通过某些方式,让两端建立通信交换基本信息。有两种方式:TCP/IP 和 RDMA CM,如下图 3.8 所示。
图 3.8
以 socket 交换方式为例,双方约定号消息格式,将需要传递的信息通过 socket 交换就好了。图 3.8 中 LID 是本端 RDMA 适配器激活后分配的 ID,在本端唯一,而 PSN 是本端发送到对端第一个数据包序号,可以随机指定。信息交换完毕后即可关闭上述连接。
至此,目的集合已经准备好,有 raddr、rkey、rGID、rQPN,加 r 表示远端(对端)的意思。万事具备只欠东风。
3.3 工作阶段
3.3.1 下发工作请求
本端在下发工作请求前,还需要处理 rQPN 和 rGID,这里以 RC 链接(类似于 TCP 链接)为例。本端需要将 QP(节点 A)与对端 QP(节点 x)绑定,在 QPC 中填入对端 QPN,同时又因为是 RC 链接(点到点),还需在 QPC 中填入 rGID。
现在可以填写工作请求了,这个请求结构称为 WQE,即工作请求元素,主要由三部分组成,控制头,远端地址和远端秘钥,本端地址、本端秘钥、数据大小,如下图 3.9 所示。
图 3.9
结合图 3.5,向 bar 虚拟内存的 Doorbell 地址一笔数据,通过 TLP 总线事务传输到 RDMA 网卡内部,即敲响门铃,硬件就可以开始工作了。
硬件通过 Doorbell 地址偏移计算出 QPN 找到对应的 QPC,从而找到 SQ 中的 WQE,通过 DMA 控制器把 WQE 搬运到内部解析,再通过 lkey 找到对应的映射表,然后将 laddr 转换获得数据所在物理页,最终从物理页取得数据组包,如下图 3.10 所示。
图 3.10
硬件还会在数据包中添加对端 raddr 和 rkey,再从 QPC 中取得对端 rGID、rQPN,这样数据包才能到对端宿主机。对端接收到数据包后,根据 rkey 找到映射表,将 raddr 翻译,最后将数据写入对应离散物理页中,注意,这个过程对端的 cpu 是不知道的(需要本端主动通知对端),完全由 RDMA 网卡完成,不需要内核参与,在对端的 app 侧看来,就是有人往某块连续的虚拟内存写了数据。
3.3.2 write 流程简介
在两方完成准备阶段并交换信息后,操作流程如下图 3.11 所示。
图 3.11
将发送 write 请求的这侧称为请求端,另一侧称为响应端;
① 请求端 A 下发 write 请求的 WQE(src_addr、len、dst_addr、r_key),里面包含双方地址信息及秘钥;
② 请求端 A 硬件(RDMA 网卡)从 SQ 队列中取得 WQE,获取源 - 目的 - 长度,这三要素;
③ 请求端 A 硬件(RDMA 网卡)从内存 src_addr 地址取得长度为 len 的数据并组装成数据报文;
④ 请求端 A 硬件(RDMA 网卡)将数据报文发送至响应端 B;
⑤ 响应端 B 硬件检查秘钥无误后,根据 rkey 查找到映射表,将数据写至 dst_addr 地址对应的物理页中;
⑥ 响应端 B 硬件向请求端 A 硬件返回操作结果;
⑦ 请求端 A 硬件根据响应端 B 的反馈结果上报工作完成 CQE,操作成功或失败,失败有错误码;
⑧ 请求端 A 的 APP 查看 CQE 获取工作完成情况。
其中 CQ 完成队列,存放的 CQE 是完成队列元素。
via:
-
Introduction to Remote Direct Memory Access (RDMA)
http://www.rdmamojo.com/2014/03/31/remote-direct-memory-access-rdma/ -
深入浅出全面解析 RDMA-CSDN博客 Master.TJ 于 2018-06-04 11:36:54 发布
https://blog.csdn.net/qq_21125183/article/details/80563463 -
RDMA (远程直接内存访问) 原理架构图文详解 + 与传统通信模式对比_rdma 内存访问过程 - CSDN 博客 fine_rain 于 2019-05-29 22:49:31 发布
https://blog.csdn.net/qq_40323844/article/details/90680159 -
DMA、链式 DMA、RDMA(精华讲解)-CSDN 博客 caodongwang 已于 2023-07-25 15:00:59 修改
https://blog.csdn.net/zz2633105/article/details/119519952