RDMA 基本操作类型详解:从双端通信到单端直访

RDMA 基本操作类型,如果对应到内核协议栈方案中,就是应用程序调用套接字 API 执行的 Send、Receive 之类的数据收发操作。RDMA 也支持 Send 和 Receive,除此之外,它还支持其他一系列操作。

本文将重点介绍 Send 和 ReceiveRDMA WriteRDMA Read 三种基本的 RDMA 操作类型,并简要介绍其他操作类型。此外,还会介绍 MR 和 PD 机制,用来解决在实际的数据收发过程中遇到的获取物理地址、换页以及安全保障相关的问题。


一、Send 和 Receive:双端操作

1.1 核心概念

Send(发送)和 Receive(接收)是一种双端操作,因为完成一次通信过程需要两端 CPU 共同参与,并且接收端需要提前显式地下发 WQE 给硬件,否则硬件不知道如何处理接收到的数据(比如应该把数据保存到内存中的哪个地方)。

1.2 操作流程

一次 Send 和 Receive 操作的过程:

复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                      计算机 1(发送端)                                  │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  应用程序                                                                │
│      │                                                                  │
│      │ 调用 ibv_post_send                                               │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                        WR(工作请求)                           │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      │                                                                  │
│      ▼                                                                  │
│  驱动程序                                                                │
│      │                                                                  │
│      │ 向 SQ 添加 WQE                                                  │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                       SQ(发送队列)                            │    │
│  │  ┌──────────────────────────────────────────────────────────┐  │    │
│  │  │ WQE 0                                                     │  │    │
│  │  │ opcode = Send                                             │  │    │
│  │  │ addr = 0x12340000                                         │  │    │
│  │  │ len = 100                                                 │  │    │
│  │  └──────────────────────────────────────────────────────────┘  │    │
│  │  │ WQE 1 │ WQE 2 │ ...                                       │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      │                                                                  │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 源数据缓存 addr: 0x12340000, len = 100                          │
│      │                                                                  │
│      ▼                                                                  │
│  RDMA 网卡                                                              │
│      │ 从 SQ 获取 WQE                                                  │
│      │ 通过 DMA 读取主机内存数据                                        │
│      │                                                                  │
└──────┼──────────────────────────────────────────────────────────────────┘
       │
       │ 网络链路
       ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                      计算机 2(接收端)                                  │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  RDMA 网卡                                                              │
│      │ 接收网络数据                                                     │
│      │ 根据 RQ 的 WQE 将数据写入主机内存                                │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 目的数据缓存 addr: 0x11110000, len = 100                        │
│      ▼                                                                  │
│  驱动程序                                                                │
│      │ 管理 RQ                                                          │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                       RQ(接收队列)                            │    │
│  │  ┌──────────────────────────────────────────────────────────┐  │    │
│  │  │ WQE 0                                                     │  │    │
│  │  │ addr = 0x11110000                                         │  │    │
│  │  │ len = 100                                                 │  │    │
│  │  └──────────────────────────────────────────────────────────┘  │    │
│  │  │ WQE 1 │ WQE 2 │ ...                                       │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      ▲                                                                  │
│      │ 向 RQ 添加 WQE(提前下发)                                       │
│      │                                                                  │
│  应用程序                                                                │
│      │ 调用 ibv_post_recv                                               │
│      │                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                        WR(工作请求)                           │    │
│  └────────────────────────────────────────────────────────────────┘    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

1.3 关键特点

特点 说明
双端操作 完成一次通信需要两端 CPU 共同参与
提前准备 接收端必须提前下发 WQE 给硬件
发送端无感知 发送端不知道发送的数据会被保存到接收端哪段缓存
每次准备 发送端每次发送数据时,接收端都要提前准备好接收数据的缓存

1.4 API 调用

操作 API 说明
Send ibv_post_send 发送端调用,向 SQ 添加发送任务
Receive ibv_post_recv 接收端调用,向 RQ 添加接收任务

重要说明:

发送端和接收端都需要轮询到 CQE 后,才能知道自己之前发起的操作是否完成。


二、RDMA Write:单端主动写入

2.1 核心概念

RDMA Write 操作是一种由本地软件发起的主动写入远端内存的行为。

关键特点:

特点 说明
单端操作 远端 CPU 不需要参与,也感知不到何时有数据写入以及何时写入完毕
主动写入 本地应用程序直接写入远端内存
权限控制 需要提前获取远端内存的地址和密钥

2.2 准备阶段

在发起 RDMA Write 操作前,需要先做好一定的准备:

复制代码
准备阶段:
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. 两端应用程序提前分配好缓存                                           │
│ 2. 两端应用程序注册 MR(Memory Region)                                 │
│ 3. 互相交换缓存地址和密钥等信息                                         │
│    ├─ 方式一:通过 Send 和 Receive 操作完成                             │
│    └─ 方式二:通过套接字通信完成                                        │
└─────────────────────────────────────────────────────────────────────────┘

2.3 操作示意

复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                          计算机 1                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  应用程序                                                                │
│      │                                                                  │
│      │ 调用 ibv_post_send                                               │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                       SQ(发送队列)                            │    │
│  │  ┌──────────────────────────────────────────────────────────┐  │    │
│  │  │ WQE 1                                                     │  │    │
│  │  │ opcode = RDMA_Write                                       │  │    │
│  │  │ addr = 0x12340000           (本地源地址)                │  │    │
│  │  │ remote_addr = 0x11110000    (远端目的地址)              │  │    │
│  │  │ len = 100                                                 │  │    │
│  │  │ key = R_key                  (远端密钥)                 │  │    │
│  │  └──────────────────────────────────────────────────────────┘  │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      │                                                                  │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 源数据缓存 addr: 0x12340000, len = 100                          │
│      │                                                                  │
│      ▼                                                                  │
│  RDMA 网卡                                                              │
│      │ 从 SQ 获取 WQE                                                  │
│      │ 通过 DMA 读取主机内存数据                                        │
│      │                                                                  │
└──────┼──────────────────────────────────────────────────────────────────┘
       │
       │ 网络链路
       ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                          计算机 2                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  RDMA 网卡                                                              │
│      │ 接收网络数据                                                     │
│      │ 将数据写入主机内存                                               │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 目的数据缓存 addr: 0x11110000, len = 100                        │
│                                                                         │
│  注意:远端 CPU 不参与此过程!                                           │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

2.4 实际工作流程

一次 RDMA Write 操作的实际工作流程包括以下步骤:

复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                              请求端                                      │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  主机内存(MR)                                                          │
│      │ 源数据缓存                                                       │
│      │                                                                  │
│      ▼                                                                  │
│  软件(驱动程序)                                                        │
│      │ ① 向 QP 的 SQ 下发 WQE                                          │
│      │ ⑧ 轮询 CQ 获取 CQE 得到任务完成信息                              │
│      │                                                                  │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                           QP                                    │    │
│  │  ┌─────────────────────┐  ┌─────────────────────┐             │    │
│  │  │         SQ          │  │         RQ          │             │    │
│  │  │ │ WQE 0 │ ...       │  │ │ ... │ ...         │             │    │
│  │  └─────────────────────┘  └─────────────────────┘             │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      │                                                                  │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                           CQ                                    │    │
│  │  │ CQE 0 │ ... (⑦ 新增 CQE 0)                                │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      ▲                                                                  │
│      │                                                                  │
│      ▼                                                                  │
│  RDMA 网卡                                                              │
│      │ ② 从 SQ 取 WQE 解析                                             │
│      │    获得源数据缓存和目的数据缓存的虚拟地址                        │
│      │    获得数据量(长度)、远端密钥(R_Key)等信息                   │
│      │ ③ 查询 MR 地址转换表,得到物理地址                              │
│      │    通过 DMA 将数据从主机内存复制到硬件缓存                       │
│      │    按协议封装数据包                                             │
│      │ ④ 将数据包通过物理链路发送给响应端网卡                          │
│      │ ⑦ 收到 ACK 后,向 CQ 添加 CQE                                   │
│      │                                                                  │
└──────┼──────────────────────────────────────────────────────────────────┘
       │
       │ ④ 网络链路(发送数据包)
       │
       ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                              响应端                                      │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  RDMA 网卡                                                              │
│      │ ⑤ 接收到数据包                                                  │
│      │    按协议解析出应用数据和目的数据缓存的虚拟地址                  │
│      │    查询本地 MR 地址转换表,将虚拟地址转换成物理地址              │
│      │    把应用数据写入目的数据缓存                                    │
│      │ ⑥ 回复 ACK 报文给请求端网卡                                     │
│      │                                                                  │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 目的数据缓存                                                     │
│                                                                         │
│  注意:响应端 CPU 全程不参与!                                           │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

2.5 流程步骤详解

步骤 位置 操作内容
请求端软件 向 SQ 中添加一个 WQE,下发 RDMA Write 任务给网卡
请求端网卡 从 SQ 中取出 WQE 并解析,获得源 / 目的数据缓存的虚拟地址、数据量、远端密钥等信息
请求端网卡 查询 MR 地址转换表得到物理地址,通过 DMA 将数据从主机内存复制到硬件缓存,封装数据包
请求端网卡 将数据包通过物理链路发送给响应端网卡
响应端网卡 接收数据包,解析应用数据和目的地址,查询 MR 地址转换表,将数据写入目的数据缓存
响应端网卡 回复 ACK 报文给请求端网卡
请求端网卡 收到 ACK 后,添加一个 CQE 到 CQ 中
请求端软件 通过轮询得到 CQE,取得任务完成信息

2.6 核心价值

一旦远端的 CPU 把内存授权给本地应用程序使用,便不再参与数据收发的过程,从而解放了远端 CPU ,也降低了通信的时延

RDMA 的内涵所在:

本地应用程序通过准备阶段获取了对端数据缓存的地址和密钥,相当于获得了一块远端内存的读写权限。拿到权限之后,本地应用程序就可以像访问本地主机的内存一样直接对这一远端内存区域进行读写,这也是 RDMA(远程直接存储器访问)的内涵所在。

重要说明:

本地应用程序是通过虚拟地址来读写远端内存的;实际操作过程中地址的转换由两端的 RDMA 网卡完成。


三、RDMA Read:单端主动读取

3.1 核心概念

RDMA Read 也是一种单端操作,其在工作机制和流程方面和 RDMA Write 非常相似。

与 RDMA Write 的主要差别:

对比项 RDMA Write RDMA Read
操作码 IBV_WR_RDMA_WRITE IBV_WR_RDMA_READ
数据方向 本地 → 远端 远端 → 本地
行为 主动写入远端内存 主动读取远端内存

3.2 操作示意

复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                          计算机 1                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  应用程序                                                                │
│      │                                                                  │
│      │ 调用 ibv_post_send                                               │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                       SQ(发送队列)                            │    │
│  │  ┌──────────────────────────────────────────────────────────┐  │    │
│  │  │ WQE 1                                                     │  │    │
│  │  │ opcode = RDMA_Read                                        │  │    │
│  │  │ addr = 0x12340000           (本地目的地址)              │  │    │
│  │  │ remote_addr = 0x11110000    (远端源地址)                │  │    │
│  │  │ len = 100                                                 │  │    │
│  │  │ key = R_key                  (远端密钥)                 │  │    │
│  │  └──────────────────────────────────────────────────────────┘  │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      │                                                                  │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 目的数据缓存 addr: 0x12340000, len = 100                        │
│      │ (数据将写入此处)                                               │
│      │                                                                  │
│      ▼                                                                  │
│  RDMA 网卡                                                              │
│      │ 从 SQ 获取 WQE                                                  │
│      │ 通过网络链路发送请求                                             │
│      │ 接收响应后将数据写入主机内存                                     │
│      │                                                                  │
└──────┼──────────────────────────────────────────────────────────────────┘
       │
       │ 网络链路(发送请求)
       │
       ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                          计算机 2                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  RDMA 网卡                                                              │
│      │ 接收网络请求                                                     │
│      │ 从主机内存读取数据                                               │
│      │ 通过网络链路回传数据                                             │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 源数据缓存 addr: 0x11110000, len = 100                          │
│      │ (数据从此处读取)                                               │
│                                                                         │
│  注意:远端 CPU 不参与此过程!                                           │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

3.3 实际工作流程

一次 RDMA Read 操作的实际工作流程:

复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                              请求端                                      │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  主机内存(MR)                                                          │
│      │ 目的数据缓存                                                     │
│      │                                                                  │
│      ▼                                                                  │
│  软件(驱动程序)                                                        │
│      │ ① 向 QP 的 SQ 下发 WQE                                          │
│      │ ⑧ 读取 CQE 获得任务完成信息                                      │
│      │                                                                  │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                           QP                                    │    │
│  │  ┌─────────────────────┐  ┌─────────────────────┐             │    │
│  │  │         SQ          │  │         RQ          │             │    │
│  │  │ │ WQE 0 │ ...       │  │ │ ... │ ...         │             │    │
│  │  └─────────────────────┘  └─────────────────────┘             │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      │                                                                  │
│      ▼                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │                           CQ                                    │    │
│  │  │ CQE 0 │ ... (⑦ 新增 CQE 0)                                │    │
│  └────────────────────────────────────────────────────────────────┘    │
│      ▲                                                                  │
│      │                                                                  │
│      ▼                                                                  │
│  RDMA 网卡                                                              │
│      │ ② 从 SQ 取 WQE 解析                                             │
│      │    获得对端源数据缓存和本地目的数据缓存的虚拟地址                │
│      │    获得数据量(长度)、远端密钥(R_Key)等信息                   │
│      │ ③ 将 RDMA Read 请求数据包通过物理链路发送给响应端网卡           │
│      │ ⑥ 收到数据包,解析并提取出数据                                  │
│      │    查询 MR 地址转换表,获得目的数据缓存的物理地址                │
│      │    将数据写入目的数据缓存                                        │
│      │ ⑦ 向 CQ 添加 CQE                                                │
│      │                                                                  │
└──────┼──────────────────────────────────────────────────────────────────┘
       │
       │ ③ 网络链路(发送请求)
       │
       ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                              响应端                                      │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  RDMA 网卡                                                              │
│      │ ④ 收到数据包                                                    │
│      │    解析出源数据缓存的虚拟地址                                    │
│      │    查询本地 MR 地址转换表,转换成物理地址                        │
│      │    从此地址读取数据,复制到硬件内部缓存                          │
│      │ ⑤ 将数据封装成回复数据包,发送到物理链路                        │
│      │                                                                  │
│      ▼                                                                  │
│  主机内存(MR)                                                          │
│      │ 源数据缓存                                                       │
│                                                                         │
│  注意:响应端 CPU 全程不参与!                                           │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

3.4 流程步骤详解

步骤 位置 操作内容
请求端软件 向 SQ 中添加一个 WQE,下发 RDMA Read 任务给网卡
请求端网卡 从 SQ 中取出 WQE 并解析,获得对端源 / 本地目的数据缓存的虚拟地址、数据量、远端密钥等信息
请求端网卡 将 RDMA Read 请求数据包通过物理链路发送给响应端网卡
响应端网卡 收到数据包,解析出源数据缓存的虚拟地址,查询 MR 地址转换表,转换成物理地址,读取数据到硬件缓存
响应端网卡 将数据封装成回复数据包,发送到物理链路
请求端网卡 收到数据包,解析并提取出数据,查询 MR 地址转换表获得物理地址,将数据写入目的数据缓存
请求端网卡 添加一个 CQE 到 CQ 中
请求端软件 读取 CQE,获得任务完成信息

3.5 关键说明

RDMA Read 跟 RDMA Write 是相反的过程,是本地应用程序主动读取远端内存的行为。同 RDMA Write 一样,除了准备阶段,远端 CPU 不需要参与,也感知不到数据被从内存中读取的过程。

重要说明:

读取到的数据,是在对端回复的报文中携带来的。


四、其他 RDMA 操作类型

4.1 操作码定义

除了前文已经介绍的几个最常见的 RDMA 操作类型,还有其他类型的 RDMA 操作。每种 RDMA 操作类型都对应一个填写到 WQE 中的操作码。

操作码定义(来自 rdma-core/libibverbs/verbs.h):

复制代码
enum ibv_wr_opcode {
    IBV_WR_RDMA_WRITE,              // RDMA 写
    IBV_WR_RDMA_WRITE_WITH_IMM,     // 带立即值的 RDMA 写
    IBV_WR_SEND,                    // 发送
    IBV_WR_SEND_WITH_IMM,           // 带立即值的发送
    IBV_WR_RDMA_READ,               // RDMA 读
    IBV_WR_ATOMIC_CMP_AND_SWP,      // 原子比较和交换
    IBV_WR_ATOMIC_FETCH_AND_ADD,    // 原子获取和加
    IBV_WR_LOCAL_INV,               // 本地失效
    IBV_WR_BIND_MW,                 // 绑定内存窗口
    IBV_WR_SEND_WITH_INV,           // 带失效的发送
    IBV_WR_TSO,                     // TCP 分段卸载
    IBV_WR_DRIVER1,                 // 驱动自定义
};

4.2 带立即值的发送

操作码: IBV_WR_SEND_WITH_IMM

特点:

特点 说明
立即值传输 发送端即时传输 32 位的数据(称为立即值)
不包含在数据中 该值作为接收通知的一部分发送给接收端,不包含在数据缓存中
CQE 携带 接收端应用程序通过读取 CQE 中的某个字段获取立即值

与普通 Send 的区别:

复制代码
普通 Send:
  发送端 → 数据 → 接收端
  接收端必须事先下发接收缓存

带立即值的 Send:
  发送端 → 数据 + 32位立即值 → 接收端
  立即值不写入数据缓存,而是通过 CQE 传递给接收端应用程序

4.3 带立即值的 RDMA 写

操作码: IBV_WR_RDMA_WRITE_WITH_IMM

与普通 RDMA Write 的区别:

对比项 普通 RDMA Write 带立即值的 RDMA Write
远端通知 不通知远端应用程序 会通知远端应用程序
RQ 消耗 不消耗远端 RQ 的 WQE 消耗远端 RQ 的一个 WQE
立即值传递 32 位立即值通过 CQE 传递

流程说明:

复制代码
1. 远端应用程序先发起一次 Receive 操作
2. 远端应用程序轮询 CQE
3. 本地应用程序发起带立即值的 RDMA 写
4. 立即值不会写入远端内存
5. 立即值作为 CQE 的一部分被远端应用程序获取

4.4 原子操作

原子获取和加

操作码: IBV_WR_ATOMIC_FETCH_AND_ADD

功能:

复制代码
以原子方式:
1. 将指定内存地址中的值增加指定的数值
2. 将加之前的数值返回给调用者
原子比较和交换

操作码: IBV_WR_ATOMIC_CMP_AND_SWP

功能:

复制代码
以原子方式:
1. 将某个内存地址中的数值与指定数值进行比较
2. 如果它们相等,则另一个新值将被写入该内存地址

概念性代码示例:

复制代码
int CAS(long *addr, long old, long new)
{
    /* 原子执行 */
    if(*addr != old)
        return 0;  // 比较失败,不写入
    *addr = new;
    return 1;      // 比较成功,写入新值
}

CAS 的作用:

原子比较和交换(CAS)是原子操作的一种,可用于在多线程编程中实现不被打断的数据交换操作,从而避免多线程同时写某一数据时由于执行顺序的不确定性以及中断的不可预知性产生的数据不一致问题。

应用场景:

复制代码
1. 记录下某块内存中的旧值
2. 对旧值进行一系列的操作后得到新值
3. 通过 CAS 操作将新值与旧值进行交换

结果:
  - 如果内存中的值未被修改过 → CAS 成功,内存值更新为新值
  - 如果内存中的值已被修改过 → CAS 失败,新值不写入内存

五、RDMA 操作类型总结

5.1 操作类型对比

操作类型 操作码 类型 远端 CPU 参与 数据方向 典型场景
Send IBV_WR_SEND 双端 需要 本地 → 远端 控制消息、小数据
Receive - 双端 需要 本地 ← 远端 配合 Send 使用
RDMA Write IBV_WR_RDMA_WRITE 单端 不需要 本地 → 远端 大数据传输、日志复制
RDMA Read IBV_WR_RDMA_READ 单端 不需要 本地 ← 远端 远程内存访问、分布式缓存
Send With Imm IBV_WR_SEND_WITH_IMM 双端 需要 本地 → 远端 + 32 位立即值 带通知的消息传递
RDMA Write With Imm IBV_WR_RDMA_WRITE_WITH_IMM 单端 通知 本地 → 远端 + 32 位立即值 带通知的数据写入
Atomic Fetch and Add IBV_WR_ATOMIC_FETCH_AND_ADD 单端 不需要 原子操作 分布式计数器
Atomic CAS IBV_WR_ATOMIC_CMP_AND_SWP 单端 不需要 原子操作 分布式锁、无锁数据结构

5.2 双端操作 vs 单端操作

复制代码
双端操作:
┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│  发送端                              接收端                              │
│    │                                   │                                │
│    │ Post Send                         │ Post Receive(提前准备)        │
│    ▼                                   ▼                                │
│    │                                   │                                │
│    │ ───────── 数据 ─────────────────→ │                                │
│    │                                   │                                │
│    │                                   ▼                                │
│    │                              数据写入缓存                           │
│    │                                   │                                │
│    │                              轮询 CQE                              │
│    ▼                                   │                                │
│  轮询 CQE                               │                                │
│                                                                         │
│  特点:两端 CPU 都参与数据收发过程                                        │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

单端操作:
┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│  请求端                              响应端                              │
│    │                                   │                                │
│    │ Post Send(准备阶段获取地址/密钥)  │                                │
│    ▼                                   │                                │
│    │                                   │                                │
│    │ ───────── 数据 ─────────────────→ │                                │
│    │                                   │                                │
│    │                                   ▼                                │
│    │                              数据写入缓存                           │
│    │                              (CPU 不感知!)                       │
│    │                                   │                                │
│    ▼                                   │                                │
│  轮询 CQE                               │                                │
│                                                                         │
│  特点:响应端 CPU 全程不参与数据收发过程                                  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

5.3 术语说明

术语 说明 适用场景
发送端 / 接收端 Send/Receive 双端操作 描述双端操作
请求端 / 响应端 RDMA Write/Read 单端操作 描述单端操作,不易产生歧义

六、关键设计理念

6.1 虚拟地址与物理地址转换

复制代码
应用程序使用虚拟地址:
  - WQE 中填写的是虚拟地址
  - 应用程序通过虚拟地址来读写远端内存

实际操作中的地址转换:
  - 由两端的 RDMA 网卡完成
  - 网卡查询 MR 地址转换表
  - 将虚拟地址转换成物理地址
  - 然后进行 DMA 操作

6.2 MR 地址转换表

概念 说明
MR(Memory Region) 内存区域,应用程序注册的内存块
地址转换表 虚拟地址到物理地址的映射表
查询主体 RDMA 网卡硬件
作用 支持虚拟地址访问,实现内存保护

6.3 权限控制机制

复制代码
准备阶段:
  1. 远端应用程序分配内存缓存
  2. 远端应用程序注册 MR,获得 R_Key
  3. 远端应用程序将虚拟地址 + R_Key 发送给请求端
  4. 请求端获得远端内存的访问权限

执行阶段:
  - 请求端在 WQE 中填写远端虚拟地址和 R_Key
  - 响应端网卡验证 R_Key 的有效性
  - 验证通过后允许访问

安全保障:
  - 只有持有正确 R_Key 的请求才能访问对应内存
  - MR 可以设置访问权限(只读/只写/读写)

0voice · GitHub

相关推荐
todoitbo2 小时前
用虚拟局域网打通 Win/Mac/Linux 三端:跨设备协作的实用方案
linux·运维·macos
森林猿2 小时前
java-modbus-读取-modbus4j
java·网络·python
csdn_aspnet2 小时前
AD域网络位置异常深度排错指南:从DNS到GPO的完整诊断链
网络·ad·dns··netlogon
Simon_lca2 小时前
突破合规瓶颈:ZDHC Supplier to Zero(工厂零排放 - 进阶型)体系全攻略
大数据·网络·人工智能·分类·数据挖掘·数据分析·零售
Sylvia-girl3 小时前
Linux下的基本指令1
linux·运维·服务器
wyt5314293 小时前
Redis的安装教程(Windows+Linux)【超详细】
linux·数据库·redis
17(无规则自律)3 小时前
【Linux驱动实战】:字符设备之ioctl与mutex全解析
linux·c语言·驱动开发·嵌入式硬件
黄焖鸡能干四碗4 小时前
网络安全建设实施方案(Word文件参考下载)
大数据·网络·人工智能·安全·web安全·制造
天赐学c语言4 小时前
Linux - 应用层自定义协议与序列/反序列化
linux·服务器·网络·c++