--- tags : Session one title : data-path flow/memory management/verbs in short (應凱軒) --- # Session one RDMA Foundation 1. 何謂RDMA 允許使用者態的應用程式直接讀取或寫入遠端記憶體。 2. DMA 直接記憶體存取,而不用通過CPU,可以直接寫入記憶體。  3. WQ WQE CQ CQE a. WQE 簡單來說就是按順序儲存軟體給硬體下發的任務 舉例來說某一份任務是這樣的:“我想把位于地址0x12345678的長度為10byte的數據發送给對面的節點,硬體接到任務之后,就會通過DMA去記憶體中取數據,组裝數據包,然后發送。WQE的含意應該比較明確了。而其中的Queue 是一種先進先出的數據結構。 b. WQ 了解WQE後,就可以很簡單的來了解WQ了 它就是用來存放“任務書”的“文件夾”,WQ里面可以容纳很多WQE。 c. CQE 其實跟WQE的方向類似,只是他是在硬體完成任務後返回給軟體的。 d. CQ 跟WQ的意思一樣。  ## WQ的概念圖  ## CQ的概念圖 而一整個QP看起來就會像這樣子  1. 接收端硬體從RQ中拿到任務,準備接收數據。 2. 發送端APP以WQE的形式下發一次SEND任務。 3. 發送端硬體從SQ中拿到任務,從記憶體中拿到待發送數據,组裝數據包。 4. 發送端網卡將數據包通過物理鏈路發送给接收端網卡。 5. 接收端收到數據,進行校驗后回復ACK封包给發送端。 6. 接收端硬體將數據放到WQE中指定的位置,然后生成“任務報告”CQE,放置到CQ中。 7. 接收端APP取得任务完成信息。 8. 發送端網卡收到ACK(確認資料有無正確傳輸到接收端)后,生成CQE,放置到CQ中。 9. 发送端APP取得任务完成信息。 ### 然而我們再細看的話  用戶端傳送資料時會通過verbs 而verbs為 " 一組標準動作,又類似於一個function - 那旁邊的SGL呢? SGL(Scatter/Gather List)是最基本的數據組織形式。 而SGL為SGE組合而成的,那每一個SGE就是一個Data Segment(資料區段)也就是DS。RDMA支持Scatter/Gather操作, - 具體來講就是RDMA可以支持一個連續的Buffer空間,進行Scatter分散到多個目的主機的不連續的Buffer空間。Gather指的就是多個不連續的Buffer空間,可以Gather到目的主機的一段連續的Buffer空間。 - 以下為一個ibv_sge的定義 ``` C++ struct ibv_sge { uint64_t address; //資料區段所在的虛擬記憶體 uint32_t length; //資料區段長度 uint32_t lkey; // 該資料區段對應的L_key }; ``` - 而這裡就可以細講Verbs了 - 在數據傳輸中,發送/傳輸的Verbs API為 ###### ibv_post_send() - post a list of work requests (WRs) to a send queue 將一個WR列表放置到發送隊列中 ###### ibv_post_recv() - post a list of work requests (WRs) to a receive queue 將一個WR列表放置到接收隊列中 ibv_post_send的結構 ```c++ #include <infiniband/verbs.h> int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, struct ibv_send_wr **bad_wr); ``` 而其中ibv_send_wr的結構 ``` struct ibv_send_wr { uint64_t wr_id; /* User defined WR ID */ struct ibv_send_wr *next; /* Pointer to next WR in list, NULL if last WR */ struct ibv_sge *sg_list; /* Pointer to the s/g array */ int num_sge; /* Size of the s/g array */ enum ibv_wr_opcode opcode; /* Operation type */ int send_flags; /* Flags of the WR properties */ uint32_t imm_data; /* Immediate data (in network byte order) */ union { struct { uint64_t remote_addr; /* Start address of remote memory buffer */ uint32_t rkey; /* Key of the remote Memory Region */ } rdma; struct { uint64_t remote_addr; /* Start address of remote memory buffer */ uint64_t compare_add; /* Compare operand */ uint64_t swap; /* Swap operand */ uint32_t rkey; /* Key of the remote Memory Region */ } atomic; struct { struct ibv_ah *ah; /* Address handle (AH) for the remote node address */ uint32_t remote_qpn; /* QP number of the destination QP */ uint32_t remote_qkey; /* Q_Key number of the destination QP */ } ud; } wr; }; ```  - 從上圖中,我們可以看到wr鏈表中的每一個結點都包含了一個SGL,SGL是一個數組,包含一個或多個SGE。通過ibv_post_send提交一個RDMA SEND 請求。這個WR請求中,包括一個sg_list的元素。它是一個SGE鏈表,SGE指向具體需要發送數據的Buffer。 -  - 我們在發送一段記憶體地址的時候,我們需要將這段記憶體地址通過Memory Registration註冊到RDMA中。也就是說註冊到PD記憶體保護域當中。一個SGL至少被一個MR保護, 多個MR存在同一個PD中。如圖所示一段記憶體MR可以保護多個SGE元素。 -  在上圖中,一個SGL數組包含了3個SGE, 長度分別爲N1, N2, N3字節。我們可以看到,這3個buffer並不連續,它們Scatter(分散)在記憶體中的各個地方。RDMA硬體讀取到SGL後,進行Gather(聚合)操作,於是在RDMA硬體的Wire上看到的就是N3+N2+N1個連續的字節。換句話說,通過使用SGL, 我們可以把分散(Scatter)在記憶體中的多個資料區段(不連續)交給RDMA硬體去聚合(Gather)成連續的資料區段 #### RDMA 記憶體 Memory Registration(MR) | 記憶體註冊 RDMA 就是用來對記憶體進行數據傳輸。那麼怎樣才能對記憶體進行傳输,很簡單,那就是註冊。 因為RDMA硬體對用來做數據傳輸的記憶體是有特殊要求的。 在數據傳輸的過程中,應用程序不能修改數據所在的記憶體。 操作系统不能對數據所在的記憶體進行page out操作 -- 實體地址和虛擬地址的映射必须是固定不變的。 注意無論是DMA或者RDMA都要求實體地址連續,這是由DMA引擎所决定的。 那麼怎麼進行記憶體註冊呢? 創建兩個key (local和remote)指向需要操作的記憶體區域 註冊的keys是數據傳輸請求的一部分 註冊一个Memory Region之后,这個時候這個Memory Region也就有了它自己的屬性: context : RDMA操作上下文 addr : MR被註冊的Buffer地址 length : MR被註冊的Buffer長度 lkey:MR被註冊的本地key rkey:MR被註冊的遠程key 對Memrory Registration:Memory Registration只是RDMA中對記憶體保護的一種措施,只有將要操作的記憶體註冊到RDMA Memory Region中,這塊操作的記憶體就交给RDMA 保護域來操作了。這個時候我們就可以對這塊記憶體進行操作,至於操作的起始地址、操作Buffer的長度,可以根據程序的具體需求進行操作。我們只要保證接受方的Buffer 接受的長度大於等於發送的Buffer長度。 ### Reference https://zhuanlan.zhihu.com/p/195757767 https://www.twblogs.net/a/5c404c9ebd9eee35b3a6a3a2 https://zhuanlan.zhihu.com/p/55142557 https://zhuanlan.zhihu.com/p/141267386 https://www.zhihu.com/column/c_1231181516811390976
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up