https://zhuanlan.zhihu.com/p/336793481
簡介
Remote
- data transfers between nodes in a network
Direct
- no Operating System Kernel involvement in transfers
- everything about a transfer offloaded onto Interface Card
Memory
- transfers between user space application virtual memory
- no extra copying or buffering
Access
- send, receive, read, write, atomic operations
- RDMA通過專有的RDMA網卡RNIC,繞過內核直接從用戶空間訪問
RDMA enabled NIC
網卡。
- 要運行RDMA,除了加載mlx5_core,還有其他模塊
mlx5_ib
,ib_core
,ib_ucm
,rdma_core
- RDMA is a method of accessing memory on a remote system without interrupting the processing of the CPU(s) on that system. -- RDMA over Commodity Ethernet at Scale
rdma和普通的tcp/ip有什么不同
- zero copy – data transferred directly from virtual memory on one node to virtual memory on another node
- kernel bypass – no operating system involvement during data transfers
- asynchronous operation – threads not blocked during I/O transfers
- tcp網絡收發的過程,涉及了多個隊列和緩沖區。
- rdma鏈路免拷貝,但是要提前申請內存(pin住內存)
tcp網絡收發過程涉及的緩沖區
- 網卡收發網絡包時,通過 DMA 方式交互的環形緩沖區;
- 網卡中斷處理程序為網絡幀分配的,內核數據結構 sk_buff 緩沖區;
- 應用程序通過套接字接口,與網絡協議棧交互時的套接字緩沖區。
名詞
OFED
:目前的理解是OFED實現的是RDMA編程的接口層(編程庫),底層的協議棧是靠別的團隊完成的。libibverbs
和librdmacm
庫:libibverbs
is a library that allows userspace processes to use RDMA "verbs" as described in the InfiniBand Architecture Specification and the RDMA Protocol Verbs Specification. 其中librdmacm
在libibverbs
上封裝了一層Roce v1
:ib 二層Roce v2
:udp 三層rc
:reliable connectionuc
:unreliable connection
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對端。
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與傳統網絡傳輸的最大不同,只需提供直接訪問遠程的虛擬地址,無須遠程應用的參與其中,這種方式適用於批量數據傳輸。
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與傳統網絡傳輸的最大不同,只需提供直接訪問遠程的虛擬地址,無須遠程應用的參與其中,這種方式適用於批量數據傳輸。
read/write不會消耗srq
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,這是一種復雜的消息傳輸模式,多用於傳輸短的控制消息。
編程步驟
- 打開設備
ibv_open_device
- 申請protect-domain
ibv_alloc_pd
ibv_alloc_pd
creates a protection domain (PD). PDs limit which memory regions can be accessed by which queue pairs (QP) providing a degree of protection from unauthorized access.- 注冊內存
ibv_reg_mr
- 通過上一步申請的pd,注冊內存,同時規定使用權限,不同的pd可以訪問同一塊mr,內存可以使用一片mmap出的內存區域,也可以是
spdk_zmalloc
申請出的大頁內存 - 同時這個命令也申請出了lkey,rkey
- 可是使用任何類型的內存
- 創建Complete Queue
ibv_create_cq
, - 多個qp可以共用一個cq,sending和receiving也可以共用一個cq
- 默認是polling模式,也可以配置參數
ibv_comp_channel
配制成事件通知的模式 - 創建shared receive queue
ibv_create_srq
- 申請出的srq會被
ibv_post_srq_recv
調用 - 多個qp共用一個srq
- 創建queue-pair
ibv_create_qp
- 創建新的qp,會關聯cq,srq
- init/ready to receive/ready to send (modify_qp)
- 放置receive buffer
ibv_post_srq_recv
- 把一系列的wr放到srq中
- 接收消息的時候才要用到,因為接收方需要開辟內存放置收到的信息
- 客戶端發送消息過來的時候會占用一個當前空閑的wr,如果當前srq中沒有空閑的wr了,發送端會報錯
- 交換qp信息,建立連接
- 發送
ibv_post_send
- poll cq
ibv_poll_cq
參考鏈接
- 深入淺出全面解析RDMA
- 使用RDMA ibverbs 編程
- RDMA學習路線總結
- nvme-rdma需要使用OFDE選項with-nvmf
- HowTo Compile MLNX_OFED for Different Linux Kernel Distribution
- MLNX_OFED Documentation Rev 5.0-2.1.8.0 pdf
- Mellanox Linux Driver Modules Relationship (MLNX_OFED)
- 華為雲部署全球首個PFC-Free的RDMA網絡HUAWEI CurreNET
- 兩種以太網 RDMA 協議: iWARP 和 RoCE
- OpenVSwitch 硬件加速淺談 ovs hw-offload
- OVS Offload Using ASAP2 Direct 裸金屬實際上還是虛擬機
- Raw Ethernet Programming: Packet Pacing - Code Example
- RDMA read and write with IB verbs 寫的很好,還有例程
- RoCE Debug Flow for Linux看不懂
- RDMA技術詳解看過了,挺好的
- Understanding mlx5 Linux Counters and Status Parameters比如/sys/class/infiniband/mlx5_bond_0/ports/1/hw_counters/np_cnp_sent和 /sys/class/infiniband/mlx5_bond_0/ports/1/hw_counters/np_ecn_marked_roce_packets
- TCP中ECN詳細工作機制講解一
- RDMA/RoCE Solutionsmlx一系列的文章
- mlnx_qos
- ibv_post_send() RDMAmojo
- ibv_create_qp()
- Connecting Queue Pairs
- ibv_modify_qp()
- Revisiting Network Support for RDMA - Extended version of the SIGCOMM 2018 paper論文挺好的,很多基本概念也有,比如NACK: negative acknowledgement
- RDMA over Commodity Ethernet at Scale SIGCOMM 2016 paperguochuanxiong的論文
- Congestion Control for Large-Scale RDMA deployments 2015 sigcomm,首篇提到DCQCN的論文
- Verbs programming tutorial
- Priority Flow Control (PFC)
- 7.7. USING CHANNEL BONDING講bonding redhat真的是有很多不錯的文章
- [RoCE]擁塞控制機制(ECN, DC-QCN) ecn標記有它的不足之處,如果qpair很多,而ecn又是隨機標記的,會導致有些qpair標記不到,導致單憑ecn無法避免擁塞
- VLAN 基礎知識
- 數據中心網絡監控小結pingmesh