ibverbs文檔翻譯

百度雲下載

產品簡介

官方驅動及文檔地址:

http://www.mellanox.com/page/products_dyn?product_family=26&mtag=linux_sw_drivers

image

文檔列表

Product Brief (PB_OFED.pdf)

爲Field-Proven RDMA and Transport Offload Hardware Solutions的高性能服務器和存儲連接軟件

Benifits

  • 支持同一適配卡上的InfiniBand和以太網連接
  • 在所有Mellanox InfiniBand和以太網設備上運行的單個軟件堆棧
  • 支持HPC應用,如科學研究,油氣勘探,汽車碰撞測試
  • 用戶級verbs允許諸如MPI和UDAPL之類的協議接口到Mellanox InfiniBand和10 / 40GbE RoCE硬件。內核級別verbs允許諸如SDP,iSER,SRP之類的協議接口到Mellanox InfiniBand和10 / 40GbE RoCE硬件。
  • 通過Mellanox消息加速(MXM)提高性能和可擴展性
  • RoCEv2使L3路由能夠提供更好的隔離,並實現超大規模Web2.0和雲部署,具有出色的性能和效率
  • 支持數據中心應用程序,如Oracle 11g RAC,IBM DB2,Purescale金融服務低延遲消息傳遞應用程序,如IBM WebSphere LLM,Red Hat MRG Tibco
  • 支持大數據分析,例如RDMA NYSE Data Fabric上的Hadoop
  • 支持使用RDMA優勢的高性能存儲應用程序
  • 通過KVM和XenServer支持I / O虛擬化技術,如SR-IOV和半虛擬化
  • SDP和IPoIB組件使得TCP / IP和基於套接字的應用程序能夠受益於InfiniBand傳輸
  • 在用戶和內核級別支持OpenFabrics定義的Verbs API。
  • SCSI中間層接口,支持基於SCSI的塊存儲和管理

Mellanox OpenFabrics 企業發行版(Enterprise Distribution) for Linux(MLNX_OFED)

使用商品servers和存儲系統的集羣在不斷增長的大型市場中被廣泛部署,如高性能計算、數據倉庫、在線交易處理、金融服務和大規模的Web2.0部署。爲了實現高效率地透明式分佈式計算,市場中的應用需要最高的I/O帶寬和儘可能低的延遲。這些需求與提供一個網絡、虛擬化、存儲和其他應用程序和接口的大型交互式生態系統相結合。

開放式結構聯盟www.openfabrics.org的OFED已經通過與提供高性能I/O的供應商的協作開發測試來加強。Mellanox OFED(MLNX_OFED)是一種Mellanox測試和打包版本的OFED,並支持使用相同的RDMA(遠程DMA)和內核旁路API(稱爲OFED verbs - InfiniBand and Ethernet)兩種互連類型。Mellanox製作的10/20/40Gb/s的InfiniBand和超過10/40GbE的RoCE(基於RDMA over Converged Ethernet標準)使OEM和系統集成商能夠滿足市場中最終用戶的需求。

Linux Inbox 驅動

適用於以太網和InfiniBand的Mellanox適配器的Linux VPI驅動程序也可用於所有主要發行版,RHEL、SLES、Ubuntu等等的Inbox。Inbox驅動程序使用Mellanox高性能雲、HPC、存儲、金融服務和更多的企業級Linux發行版的開箱即用的經驗。

VPI Support

該設備通過一個高效的多層設備驅動架構使得在相同硬件I/O適配器(HCA或NIC)上的多重I/O連接選項生效。一臺服務器上安裝的相同的OFED棧可以deliver(實現)InfiniBand和以太網的同時I/O服務,端口也根據應用和終端用戶需求來重新安排。比如適配器上的一個端口可以用來作爲標準NIC或者RoCE以太網NIC,而另一個端口何以操作InfiniBand,或者兩個端口用用來運行IB後者以太網。這樣就使得IT管理人員能夠實現功能聚合和高端I/O服務。

提供聚合和高端I/O服務

數據中心環境的網絡中包含server to server通信(IPC)、server to LAN和server to SAN。在數據中心,特別是那些屬於目標市場的應用程序中,應用程序期望針對不同類型的流量進行優化的不同API或接口,以實現最高性能。

效率 & 高性能HPC(高性能計算)簇

在HPC應用中,MPI(信息通過接口)已經被廣泛作爲了並行編程通信庫。在正在形成的大規模HPC應用中,I/O瓶頸不僅僅存在於架構中,還被拓展到了通信庫。爲了對MPI、SHMEM和PGAS應用提供可擴展的解決方法,Mellanox提供了一個新的名叫MXM(MellanoX Messaging)的增量庫,該庫通過改善內存和延遲的相關效率,使MPI、SHMEM和PGAS編程語言能夠擴展到非常大的集羣,並確保通信庫可以通過Mellanox互連解決方案進行全面優化。

金融服務應用的最低延遲

使用InfiniBand、RoCE和VMA的MLNX_OFED實現了金融應用的最低延遲和最高PPS(Packet Per Second)性能。

集羣數據庫應用的最低延遲和帶寬

UDAPL是應用程序(如IBM DB2 pureScale)使用的另一個用戶級RDMA接口。

Web2.0和其他傳統的基於Socket的應用

包含IP-IB現場驗證的MLNX_OFED,使基於IP的應用程序能夠在InfiniBand上無縫工作。對於對最低延遲不敏感的應用程序,通過L2 NIC(以太網)驅動程序實現支持標準UDP/TCP/IP Socket接口。

存儲應用

爲了使傳統的基於SCSI和iSCSI的存儲應用程序享受類似的RDMA性能優勢,MLNX_OFED包括基於RDMA協議(SRP)的SCSI啓動器和目標,以及與行業中可用的各種目標組件進行互操作的iSCSI RDMA協議(iSER)。 iSER可以
在InfiniBand或RoCE上實施。 MLNX_OFED支持Mellanox存儲加速,這是一個統一的計算和存儲網絡,可以顯着優於多種網絡的性價比。

高可用性 High Availability (HA)

MLNX_OFED包括消息傳遞,套接字和存儲應用程序的高可用性支持。 通過IPoIB支持標準的Linux通道綁定模塊,可以跨同一個適配器上的端口或跨適配器進行故障切換。 類似地,使用標準Linux實現(例如設備映射器多路徑(dm-multipath)驅動程序)的SCSI應用程序支持通過SRP啓動器的標準多路徑和故障轉移。 還支持一些供應商特定的故障切換/負載平衡驅動程序模型。

RDMA Aware Networks Programing User Manual

version 1.7

Contents

  1. RDMA Architer Overview
  2. RDMA-Aware Programming Overview
  3. VPI Verbs API
  4. RDMA_CM_API
  5. RDMA Verbs API
  6. Events
  7. Programming Excmples Using IBV verbs
  8. Progamming Examples Using RDMA Verbs
  9. Experimental APIs
  10. Verbs API for Extended Atomics Support
  11. User-Mode Memory Registration (UMR)
  12. Cross-Channel Communications Support

Glossary 術語

Term Description
Access Layer 用於訪問互連結構(VPI™,InfiniBand®,以太網,FCoE)的低級操作系統基礎設施(管道)
它包括支持上層網絡協議,中間件和管理代理所需的所有基本傳輸服務
AH(Address Handle) 描述在UD(Unreliable Datagram) QP(Queue Pair)中使用的遠程端的路徑的對象
CA(Channel Adapter) 中斷InfiniBand鏈路、執行傳輸層功能的設備
CI(Channel Interface) 面向Verbs客戶的通道介紹,通過網絡適配器、相關固件和設備驅動軟件的組合實現
CM(Communication Manager) 負責建立、維護和發佈RC和UC QP(Queue Pair)服務類型通信的實體
服務ID解析協議允許UD服務的用戶定位支持其所需服務的QP(Queue Pair)
終端節點的每個IB端口都有一個CM
Compare & Swap 指示遠程QP(Queue Pair)讀取64位值,將其與提供的比較數據進行比較,如果相等,則將其替換爲QP(Queue Pair)中提供的交換數據。
CQ(Completion Queue) 包含CQEs的先進先出隊列
CQE(Completion Queue Entry) CQ(Completion Queue)中描述完成WR(Work Request)信息的條目(狀態大小等)
DMA(Direct Memory Access) 允許硬件繞過CPU直接將數據塊移入或移出存儲器
Fetch & Add 指示遠程QP(Queue Pair)讀取64位值,並將其替換爲QP(Queue Pair)中提供的64位值和添加的數據值之和
GUID(Global Unique IDentifier) 唯一標識子網中設備或組件的64位數
GID(Global IDentifier) 用於標識網絡適配器上的端口、路由器上的端口或組播組的128位標識符
GID是有效的128位IPv6地址(根據RFC 2373),在IBA中定義了額外的屬性/限制,以促進有效的發現,通信和路由
GRH(Global Routing Header) 用於通過子網邊界遞送數據包並用於傳送多播消息的數據包頭
該Packet報頭基於IPv6協議
Network Adapter 允許在網絡中的計算機之間進行通信的硬件設備
Host 執行可控制一個或多個網絡適配器的操作系統的計算機平臺
IB InfiniBand
Join Operation IB端口必須通過向SA(Subnet Administrator)發送請求來接收多播數據包來顯式加入組播組
lkey 在註冊MR(Memory Region)時接收到的號碼,由本地WR(Work Request)來使用,以識別內存區域及其相關權限
LID(Local Identifier) 由子網管理器分配給端節點的16位地址
每個LID在其子網內是唯一的
LLE(Low Latency Ethernet) 通過CEE(Converged Enhanced Ethernet融合增強以太網)的RDMA服務,允許IB通過以太網傳輸
NA(Network Adapter) 終止鏈接並執行傳輸層功能的設備
MGID(Multicast Group ID) 由MGID標識的IB組播組由SM(Subnet Manager)管理
SM將MLID(Multicast Local Identifier)與每個MGID相關聯,並顯式地對結構中的IB交換機進行編程,以確保所有端口接收到該組播組的數據包
MR(Memory Region) 已經通過准入權限註冊的連續的一組內存緩衝區。這些緩衝區需要註冊才能使網絡適配器使用它們。 在註冊期間,創建一個L_Key和R_Key,並與創建的內存區域相關聯
MTU (Maximum Transfer Unit) 從端口發送/接收的數據包有效載荷(不包括報頭)的最大大小
MW (Memory Window) 在綁定到現有內存註冊中的指定區域後,使得遠程訪問生效的一塊被分配的資源。每個內存窗口都有一個關聯的窗口句柄,一組訪問權限以及當前的R_Key
Outstanding Work Request WR(Work Request)被髮布到工作隊列,並且沒有輪詢完成
pkey (Partition key) pkey標識端口所屬的分區
pkey大致類似於以太網網絡中的VLAN ID
它用於指向端口的分區鍵(pkey)表中的條目
每個端口由子網管理器(SM)分配至少一個pkey
PD (Protection Domain) 其成員只能溝通彼此
AHs(Address Handle)與QP(Queue Pair)進行交互,MR(Memory Region)與WQ(Work Queue)進行交互
QP (Queue Pair) 在一個對象中打包在一起的獨立工作隊列(發送隊列和接收隊列),用於在網絡節點之間傳輸數據。
Post用於發送或接收數據的初始化
有三種類型的QP:UD(Unreliable Datagram)不可靠的數據報,UC(Unreliable Conection)不可靠的連接和 RC(Reliable Connection)可靠的連接
RC (Reliable Connection) 基於面向連接協議的QP傳輸服務類型
QP(隊列對)與另一個單個QP相關聯
消息以可靠的方式發送(根據信息的正確性和順序)
RDMA (Remote Direct Memory Access) 遠程訪問內存而不涉及遠程CPU
RDMA_CM (Remote Direct Memory Access Communication Manager) 用於設置可靠,連接和不可靠的數據報數據傳輸的API
它提供了用於建立連接的RDMA傳輸中立接口
API基於套接字,但適用於基於隊列對(QP)的語義:通信必須通過特定的RDMA設備,數據傳輸是基於消息的
Requestor 將發起數據傳輸的連接端(通過發出發送請求)
Responder 該連接端將響應來自請求者的命令,該命令可以包括寫入響應者存儲器或從響應者存儲器讀取的請求,最後是請求響應者接收消息的命令
rkey MR註冊後收到的數字,用於強制進入RDMA操作的權限
RNR (Receiver Not Ready) 在可靠的連接隊列對中,兩邊之間有一個連接但是RR(Receive Request)沒有出現在接收方
RQ (Receive Queue) 保存用戶發出的RR(Receive Request)的工作隊列
RR (Receive Request) 一個WR(Work Request)被髮布到一個RQ(Receive Queue),它描述了輸入數據使用Send操作碼而將要Write的位置
另請注意,RDMA的一次立即寫入將消耗RR(Reveive Request)
RTR (Ready To Receive) 一種QP(Queue Pair)的狀態,標誌一個RR(Receive Request)可以被髮出和處理
RTS (Ready To Send) 一種QP(Queue Pair)的狀態,標誌一個SR(Send Request)可以被髮出和處理
SA (Subnet Administrator) 用於查詢和操作子網管理數據的界面
SGE (Scatter /Gather Elements) 分散/收集元素
指向全局或本地註冊內存塊的一部分的指針的條目
該元素保存塊的起始地址,大小和lkey(及其相關權限)
S/G Array 存在於WR(Work Request)中的根據所使用的操作碼的S/G元素陣列可以從多個緩衝器收集數據,並將其作爲單個流發送或單個流分解爲多個緩衝區
SM (Subnet Manager) 配置和管理子網的實體
發現網絡拓撲
分配LID
確定路由方案並設置路由表
一個主機SM和可能的幾個從機(待機模式)
管理交換機路由表,從而建立路由
SQ (Send Queue) 保存用戶發起的SRs(Send Request)的工作隊列
SR (Send Request) 一個WR(Work Request)被髮布到一個SQ(Send Queue),描述了要傳輸多少數據,其方向和方式(操作碼將指定轉移)
SRQ (Shared Receive Queue) 存儲WQEs(Work Queue Element)的隊列,輸入信息包括任何與它有關的RC(Reliable Connection)/UC(Unreliable Connection)/UD(Unreliable Datagram)的QP(Queue Pair)
可以將多個QP(Queue Pair)與一個SRQ相關聯
TCA (Target Channel Adapter) 通道適配器,不需要支持verbs,通常用於I/O設備
UC (Unreliable Connection) 基於面向連接協議的QP傳輸服務類型,其中QP(隊列對)與另一單個QP相關聯
QP不執行可靠的協議,消息可能丟失
UD (Unreliable Datagram) 消息可以是一個分組長度並且每個UD QP可以從子網中的另一個UD QP發送/接收消息的QP傳輸服務類型消息可能會丟失,並且不能保證順序。 UD QP是唯一支持多播消息的類型。 UD數據包的消息大小限於路徑MTU
Verbs 網絡適配器功能的抽象描述
使用verbs,任何應用程序都可以創建/管理所需的對象,以便使用RDMA進行數據傳輸
VPI (Virtual Protocol Interface) 允許用戶更改端口的第2層協議
WQ (Work Queue) 發送隊列或接收隊列之一
WQE (Work Queue Element) WQE發音爲“wookie”,是工作隊列中的一個元素
WR (Work Request) 用戶發佈到工作隊列的請求。

1. RDMA Architecture Overview

1.5 Key Components

這些只是在部署IB和RoCE的優勢的背景下提出的。我們不討論電纜和連接器。

Host Channel Adapter 主機通道適配器

HCAs提供IB端節點(例如服務器)連接到IB網絡的點。
這些相當於以太網(NIC)卡,但它們做得更多。 HCAs在操作系統的控制下提供地址轉換機制,允許應用程序直接訪問HCA。相同的地址轉換機制是HCA代表用戶級應用訪問存儲器的手段。該應用程序是指虛擬地址,而HCA具有將這些地址轉換爲物理地址的能力,以影響實際的消息傳輸。

Range Extenders 範圍擴展器

InfiniBand範圍擴展通過將InfiniBand流量封裝到WAN鏈路上並擴展足夠的緩衝區來確保WAN上的帶寬被全部利用。

Subnet Manager 子網管理器

InfiniBand子網管理器爲連接到InfiniBand結構的每個端口分配本地標識符(LID),並根據分配的LID開發路由表。 IB子網管理器是軟件定義網絡(SDN)的概念,它消除了互連複雜性,並創建了非常大規模的計算和存儲基礎架構。

Switches 開關

IB交換機在概念上類似於標準網絡交換機,但是被設計爲滿足IB性能要求。實現IB鏈路層的流量控制,防止丟包,支持擁塞避免和自適應路由功能,以及高級服務質量。許多交換機包括子網管理器。需要至少一個子網管理器來配置IB結構。

2. Available Communication Operations

2.1 Available Communication on Operations

2.1.1 Send / Send With Immediate

發送操作允許您將數據發送到遠程QP的接收隊列。 接收者必須事先已經post接收buffer才能接收數據。 發送方無法控制數據在遠程主機中的位置。

可選地,immediate 4字節值可以與數據緩衝器一起發送。 該值作爲接收通知的一部分呈現給接收者,並且不包含在數據緩衝器中。

2.1.2 Receive

這是與發送操作相相應的操作。 接收主機被通知數據緩衝區已經到達,可能具有內聯immediate值。 接收應用程序負責接收緩衝區維護和發佈。

2.1.3 RDMA Read

從遠程主機讀取一段內存。 調用者指定要複製到的遠程虛擬地址就像指定本地內存地址一樣。 在執行RDMA操作之前,遠程主機必須提供適當的訪問其內存的權限。 一旦設置了這些權限,RDMA讀取操作就不會對遠程主機發出任何通知。 對於RDMA讀寫,遠程端不知道此操作已完成(除了準備權限和資源)。

2.1.4 RDMA Write / RDMA Write With Immediate

類似於RDMA讀取,但數據被寫入遠程主機。 執行RDMA寫入操作,而不通知遠程主機。

RDMA Write with immediate 操作,however, do notify the remote host of the immediate value。

2.2 Transport Modes

建立QP時可以選擇幾種不同的傳輸模式。 各種模式下的有效操作如下表所示。 此API不支持RD。

Operation UD UC RC RD
Send(with immediate) X X X X
Receive X X X X
RDMA Write(with immediate) X X X
RDMA Read X X
Atomic: Fetch and Add/Cmp and Swap X X
Max Message size MTU 1GB 1GB 1GB

2.2.1 RC

  • QP is “one to one”.
  • Message transmitted by the send queue of one QP to receive queue of other QP.
  • Transmitte is reliably delivered.
  • Packets are delivered in order 有序傳輸.
  • RC is similar to TCP.

2.2.2 UC

  • QP is “one to one”.
  • Connection is not reliable, and packet may be lost.
  • 信息傳輸失敗不會重發,異常處理需被上層協議保證。

2.2.3 UD

  • QP is “one to many”.
  • UD is similar to UDP.

2.3 Key Concepts

2.3.1 Send Request (SR)

  • SR define how much data will be sent, from where, to where, how, with RDMA.
  • struct ibv_send_wr is used to implement SRs.

2.3.2 Receive Request (RR)

  • RR定義了對於non-RDMA操作要接受data的buffers。如果沒有buffers被定義,傳輸人會嘗試一個send操作或者一個RDMA Write with immediate,同時receive not ready(RNR)錯誤將被髮出。
  • struct ibv_recv_wr is used to implement RRs.

2.3.3 Completion Queue (CQ)

  • CQ是一個對象,其中包含已發佈到工作隊列(WQ)的完成的工作請求。每一次完成都表示完成了一個特定的WR(不管成功與否)。
  • CQ是一種機制,其會通知應用有關結束了的Work Request的信息(狀態,操作碼,大小,源)。
  • CQ有n個完成隊列條目(CQE)。創建CQ時指定CQE的數量。
  • 當CQE被輪詢時,它將從CQ中刪除。
  • CQ是CQE的FIFO。
  • CQ可以服務發送隊列,接收隊列或兩者。
  • 來自多個QP的Work Queue可以與單個CQ相關聯。
  • struct ibv_cq is used to implement a CQ。

2.3.4 Memory Registration (MR)

  • MR是一種機制,其允許應用程序將一組虛擬連續的內存位置或一組物理上連續的內存位置描述爲網絡適配器,該適配器將作爲使用虛擬地址的虛擬連續緩衝區。
  • 註冊過程引導memory pages(以防止pages被換出並同時保留physical<->virtual mapping)。
  • 在註冊期間,操作系統檢查註冊塊的權限。
  • 註冊過程將virtual to pyysical地址表寫入網絡適配器。
  • 註冊內存時,會爲該區域設置權限。權限是本地寫入,遠程讀取,遠程寫入,原子和綁定。
  • 每個MR都有一個遠程key和一個本地key(r_key,l_key)。本地keys由本地HCA用於訪問本地存儲器,例如在接收操作期間。遠程鍵被提供給遠程HCA,以允許遠程進程在RDMA操作期間訪問系統內存。
  • 相同的內存緩衝區可以註冊幾次(即使具有不同的訪問權限),並且每次註冊都會產生一組不同的keys。
  • struct ibv_mr is used to implement MR.

2.3.5 Memory Window (MW)

  • MW允許應用程序對其內存的遠程訪問進行更靈活的控制。
  • MWs適用於應用程序的情況:
    • 希望以比使用註銷/註冊或註冊更少的性能損失的動態方式授予和撤銷對註冊地區的遠程訪問權限。
    • 希望爲不同的遠程代理授予不同的遠程訪問權限 和/或 在註冊的區域內的不同範圍內授予這些權限。
  • 將MW與MR相關聯的操作稱爲綁定。
  • 不同的MW可以與相同的MR重疊(具有不同訪問權限的事件)。

2.3.6 Address Vector

  • Address Vector是描述從本地節點到遠程節點的路由的對象。
  • 在每個UC/RC QP中,QP context中都有一個Address Vector。
  • 在UD QP中,應爲發送的每個SR定義Address Vector。
  • struct ibv_ah is used to implement address vectors.

2.3.7 Global Routing Header (GRH)

  • GRH用於子網之間的路由。當使用RoCE時,GRH用於在子網內進行路由,因此是強制性的。 使用GRH是強制性的,以便應用程序支持IB和RoCE。
  • 當UD QP使用全局路由時,接收緩衝區的前40個字節中將包含GRH。 該區域用於存儲全局路由信息,因此可以生成適當的地址向量來響應所接收的分組。 如果GRH與UD一起使用,RR應該總有40個字節用於此GRH。
  • struct ibv_grh is used to implement GRHs.

2.3.8 Protection Domain (PD)

  • PD的組件只能互相交互。 這些組件可以是AH,QP,MR和SRQ。
  • PD用於將隊列對與MR和MW相關聯,作爲啓用和控制網絡適配器訪問主機系統內存的方法。
  • PD也用於將不可靠的UD QP與地址句柄相AH關聯,作爲控制對UD目的地的訪問的手段。
  • struct ibv_pd is used to implement protection domains.

2.3.9 Asynchromous Events

  • 網絡適配器可以發送異步事件以通知SW關於系統中發生的事件。
  • 有兩種類型的異步事件:
    • 附屬事件:個人對象發生的事件(CQ,QP,SRQ)。 這些事件將被髮送到一個特定的過程。
    • 無關聯的事件:全局對象發生的事件(網絡適配器,端口錯誤)。 這些事件將被髮送到所有進程。

2.3.10 Scatter Gather

  • 數據正在使用散點收集元素進行收集/散佈,其中包括:
    • Address:數據將被收集或散佈到的本地數據緩衝區的地址。
    • Size:將讀取/寫入此地址的數據的大小。
    • L_key:註冊到此緩衝區的MR的本地密鑰。
  • struct ibv_sge implements scatter gather elements.

2.3.11 Polling

  • 輪詢CQ是獲取有關發佈的WR(發送或接收)的詳細信息。
  • 如果WR完成狀態bad,其餘的完成將全部bad掉(並且工作隊列將被移動到錯誤狀態)。
  • 每個沒有完成的WR(被輪詢)仍然很出色。
  • 只有在WR完成之後,發送/接收緩衝區可能被使用/重新使用/釋放。
  • 應始終檢查完成狀態。
  • 當CQE被輪詢時,它將從CQ中刪除。
  • Polling is accomplished with the ibv_poll_cq operation.

3 VPI Verbs API

3.1 Initialization

3.1.1 ibv_fork_init

int ibv_fork_init(void)

Input Parameters:
None
Output Parameters:
None
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.
  • ibv_fork_init初始化libibverbs的數據結構以安全地處理fork()函數,並避免數據損壞,不管fork()是否被明確地或隱式地調用,如在system()調用。
  • 如果所有父進程線程總是被阻塞,直到所有子進程通過exec()操作結束或更改地址空間,則不需要調用ibv_fork_init。
  • 該功能適用​​於支持madvise()(2.6.17及更高版本)的MADV_DONTFORK標誌的Linux內核。
  • 將環境變量RDMAV_FORK_SAFE或IBV_FORK_SAFE設置爲任何值與調用ibv_fork_init()具有相同的效果。
  • 將環境變量RDMAV_HUGEPAGES_SAFE設置爲任何值將告知庫檢查內核對內存區域使用的底層頁大小。如果應用程序通過庫(例如libhugetlbfs)直接或間接使用龐大的頁面,這是必需的。
  • 調用ibv_fork_init()將會降低性能,因爲每個內存註冊需要額外的系統調用,並且分配給追蹤內存區域的額外內存。精確的性能影響取決於工作負載,通常不會很大。
  • 設置RDMAV_HUGEPAGES_SAFE爲所有內存啓用增加了額外的開銷。

3.2 Device Operations

以下命令用於常規設備操作,允許用戶查詢有關係統上的設備以及打開和關閉特定設備的信息。

3.2.1 ibv_get_device_list

struct ibv_device **ibv_get_device_list (int *num_devices)

Input Parameters:
none
Output Parameters:
num_devices     (optional) If non-null, the number of devices returned in the array will be stored here
Return Value:
NULL terminated array of VPI devices or NULL on failure.

ibv_get_device_list返回系統上可用的VPI設備列表。 列表中的每個條目都是一個指向struct ibv_device的指針。

struct ibv_device結構體定義如下:

struct ibv_device
{
    struct ibv_device_ops ops;
    enum ibv_node_type node_type;
    enum ibv_transport_type transport_type;
    char name[IBV_SYSFS_NAME_MAX];
    char dev_name[IBV_SYSFS_NAME_MAX];
    char dev_path[IBV_SYSFS_PATH_MAX];
    char ibdev_path[IBV_SYSFS_PATH_MAX];
};
variable description example
ops pointers to alloc and free functions
node_type IBV_NODE_UNKNOWN
IBV_NODE_CA
IBV_NODE_SWITCH
IBV_NODE_ROUTER
IBV_NODE_RNIC
InfiniBand channel adapter
transport_type IBV_TRANSPORT_UNKNOWN
IBV_TRANSPORT_IB
IBV_TRANSPORT_IWARP
0
name kernel device name eg “mthca0” mlx5_0
dev_name uverbs device name eg “uverbs0” uverbs0
dev_path path to infiniband_verbs class device in sysfs /sys/class/infiniband_verbs/uverbs0
ibdev_path path to infiniband class device in sysfs /sys/class/infiniband/mlx5_0

ibv_device結構列表將保持有效,直到列表被釋放。 調用ibv_get_device_list後,用戶應該打開所需的設備,並通過ibv_free_device_list命令及時釋放列表。

3.2.2 ibv_free_device_list

void ibv_free_device_list(struct ibv_device **list)

Input Parameters:
list        list of devices provided from ibv_get_device_list command
Output Parameters:
none
Return Value:
none

ibv_free_device_list釋放由ibv_get_device_list提供的ibv_device結構列表。 在調用此命令之前,應打開任何所需的設備。 一旦列表被釋放,列表中的所有ibv_device結構都將無效,不能再使用。

3.2.3 ibv_get_device_name

const char *ibv_get_device_name(struct ibv_device *device)

Input Parameters:
device      struct ibv_device for desired device
Output Parameters:
none
Return Value:
Pointer to device name char string or NULL on failure.

ibv_get_device_name返回了ibv_device結構體中的設備名稱的指針。

3.2.4 ibv_get_device_guid

uint64_t ibv_get_device_guid(struct ibv_device *device)

Input Parameters:
device      struct ibv_device for desired device
Output Parameters:
none
Return Value:
64 bit GUID

ibv_get_device_guid以網絡字節順序返回設備64位全局唯一標識符(GUID)。

3.2.5 ibv_open_device

struct ibv_context *ibv_open_device(struct ibv_device *device)

Input Parameters:
device      struct ibv_device for desired device
Output Parameters:
none
Return Value:
A verbs context that can be used for future operations on the device or NULL on failure.

ibv_open_device爲用戶提供了一個verbs context,它將是所有的verbs操作的對象。

3.2.6 ibv_close_device

int ibv_close_device(struct ibv_context *context)

Input Parameters:
context     struct ibv_context from ibv_open_device
Output Parameters:
none
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_close_device關閉以前使用ibv_open_device打開的verbs context。 此操作不會釋放與context相關聯的任何其他對象。 爲了避免內存泄漏,所有其他對象必須在調用此命令之前獨立釋放。

3.2.7 ibv_node_type_str

const char *ibv_node_type_str (enum ibv_node_type node_type)

Input Parameters:
node_type   ibv_node_type enum value which may be an HCA, Switch, Router, RNIC or Unknown
Output Parameters:
none
Return Value:
A constant string which describes the enum value node_type

ibv_node_type_str返回描述節點類型枚舉值node_type的字符串。 該值可以是InfiniBand HCA,交換機,路由器,啓用RDMA的NIC或未知。

enum ibv_node_type {
    IBV_NODE_UNKNOWN = -1,
    IBV_NODE_CA = 1,
    IBV_NODE_SWITCH,
    IBV_NODE_ROUTER,
    IBV_NODE_RNIC
};

3.2.8 ibv_port_state_str

const char *ibv_port_state_str (enum ibv_port_state port_state)

Input Parameters:
port_state The enumerated value of the port state Output Parameters:
None
Return Value:
A constant string which describes the enum value port_state

ibv_port_state_str返回一個描述端口狀態枚舉值port_state的字符串。

enum ibv_port_state {
    IBV_PORT_NOP = 0,
    IBV_PORT_DOWN = 1,
    IBV_PORT_INIT = 2,
    IBV_PORT_ARMED = 3,
    IBV_PORT_ACTIVE = 4,
    IBV_PORT_ACTIVE_DEFER = 5
};

3.3 Verb Context Operations

一旦打開設備,就會使用以下命令。 這些命令允許您獲取有關設備或其端口之一的更具體信息,創建可用於進一步操作的完成隊列(CQ),完成通道(CC)和保護域(PD)。

3.3.1 ibv_query_device

int ibv_query_device(struct ibv_context *context, struct ibv_device_attr *device_attr)

Input Parameters:
context         struct ibv_context from ibv_open_device 
Output Parameters:
device_attr     struct ibv_device_attr containing device attributes
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_query_device檢索與設備關聯的各種屬性。 用戶負責對struct ibv_device_attr進行空間分配和釋放。其值將會被填寫,如果函數成功返回。

結構體定義如下:

struct ibv_device_attr
{
    char        fw_ver[64];
    uint64_t    node_guid;
    uint64_t    sys_image_guid;
    uint64_t    max_mr_size;
    uint64_t    page_size_cap;
    uint32_t    vendor_id;
    uint32_t    vendor_part_id;
    uint32_t    hw_ver;
    int         max_qp;
    int         max_qp_wr;
    int         device_cap_flags;
    int         max_sge;
    int         max_sge_rd;
    int         max_cq;
    int         max_cqe;
    int         max_mr;
    int         max_pd;
    int         max_qp_rd_atom;
    int         max_ee_rd_atom;
    int         max_res_rd_atom;
    int         max_qp_init_rd_atom;
    int         max_ee_init_rd_atom;
    enum ibv_atomic_cap atomic_cap;
    int         max_ee;
    int         max_rdd;
    int         max_mw;
    int         max_raw_ipv6_qp;
    int         max_raw_ethy_qp;
    int         max_mcast_grp;
    int         max_mcast_qp_attach;
    int         max_total_mcast_qp_attach;
    int         max_ah;
    int         max_fmr;
    int         max_map_per_fmr;
    int         max_srq;
    int         max_srq_wr;
    int         max_srq_sge;
    uint16_t    max_pkeys;
    uint8_t     local_ca_ack_delay;
    uint8_t     phys_port_cnt;
}
variable description example
fw_ver Firmware version 12.18.1000
node_guid Node global unique identifier (GUID) 9814281471509629476
sys_image_guid System image GUID 9814281471509629476
max_mr_size Largest contiguous block that can be registered 18446744073709551615
page_size_cap Supported page sizes 18446744073709547520
vendor_id Vendor ID, per IEEE 713
vendor_part_id Vendor supplied part ID 4115
hw_ver Hardware version 0
max_qp Maximum number of Queue Pairs (QP) 131072
max_qp_wr Maximum outstanding work requests (WR) on any queue 32768
device_cap_flags IBV_DEVICE_RESIZE_MAX_WR
IBV_DEVICE_BAD_PKEY_CNTR
IBV_DEVICE_BAD_QKEY_CNTR
IBV_DEVICE_RAW_MULTI
IBV_DEVICE_AUTO_PATH_MIG
IBV_DEVICE_CHANGE_PHY_PORT
IBV_DEVICE_UD_AV_PORT_ENFORCE
IBV_DEVICE_CURR_QP_STATE_MOD
IBV_DEVICE_SHUTDOWN_PORT
IBV_DEVICE_INIT_TYPE
IBV_DEVICE_PORT_ACTIVE_EVENT
IBV_DEVICE_SYS_IMAGE_GUID
IBV_DEVICE_RC_RNR_NAK_GEN
IBV_DEVICE_SRQ_RESIZE
IBV_DEVICE_N_NOTIFY_CQ
IBV_DEVICE_XRC
-914482122
max_sge Maximum scatter/gather entries (SGE) per WR for non-RD QPs 30
max_sge_rd Maximum SGEs per WR for RD QPs 30
max_cq Maximum supported completion queues (CQ) 16777216
max_cqe Maximum completion queue entries (CQE) per CQ 4194303
max_mr Maximum supported memory regions (MR) 16777216
max_pd Maximum supported protection domains (PD) 16777216
max_qp_rd_atom Maximum outstanding RDMA read and atomic operations per QP 16
max_ee_rd_atom Maximum outstanding RDMA read and atomic operations per End to End (EE) context (RD connections) 0
max_res_rd_atom Maximum resources used for incoming RDMA read and atomic operations 2097152
max_qp_init_rd_atom Maximium RDMA read and atomic operations that may be initiated per QP 16
max_ee_init_atom Maximum RDMA read and atomic operations that may be initiated per EE 0
atomic_cap IBV_ATOMIC_NONE - no atomic guarantees
IBV_ATOMIC_HCA - atomic guarantees within this device
IBV_ATOMIC_GLOB - global atomic guarantees
1
max_ee Maximum supported EE contexts 0
max_rdd Maximum supported RD domains 0
max_mw Maximum supported memory windows (MW) 16777216
max_raw_ipv6_qp Maximum supported raw IPv6 datagram QPs 0
max_raw_ethy_qp Maximum supported ethertype datagram QPs 0
max_mcast_grp Maximum supported multicast groups 2097152
max_mcast_qp_attach Maximum QPs per multicast group that can be attached 48
max_total_mcast_qp_attach Maximum total QPs that can be attached to multicast groups 100663296
max_ah Maximum supported address handles (AH) 2147483647
max_fmr Maximum supported fast memory regions (FMR) 0
max_map_per_fmr Maximum number of remaps per FMR before an unmap operation is required 2147483647
max_srq Maximum supported shared receive queues (SRCQ) 8388608
max_srq_wr Maximum work requests (WR) per SRQ 32767
max_srq_sge Maximum SGEs per SRQ 31
max_pkeys Maximum number of partitions 128
local_ca_ack_delay Local CA ack delay 16
phys_port_cnt Number of physical ports 1

3.3.2 ibv_query_port

int ibv_query_port(struct ibv_context *context, uint8_t port_num, struct ibv_port_attr *port_attr)

Input Parameters:
context         struct ibv_context from ibv_open_device
port_num        physical port number (1 is first port)
Output Parameters:
port_attr       struct ibv_port_attr containing port attributes
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_query_port檢索與端口關聯的各種屬性。 用戶應該分配一個結構體ibv_port_attr,將其傳遞給函數,並在成功返回時填寫它。 用戶有責任釋放這個結構。

結構體定義如下:

struct ibv_port_attr
{
    enum ibv_port_state     state;
    enum ibv_mtu            max_mtu;
    enum ibv_mtu            active_mtu;
    int                     gid_tbl_len;
    uint32_t                port_cap_flags;
    uint32_t                max_msg_sz;
    uint32_t                bad_pkey_cntr;
    uint32_t                qkey_viol_cntr;
    uint16_t                pkey_tbl_len;
    uint16_t                lid;
    uint16_t                sm_lid;
    uint8_t                 lmc;
    uint8_t                 max_vl_num;
    uint8_t                 sm_sl;
    uint8_t                 subnet_timeout;
    uint8_t                 init_type_reply;
    uint8_t                 active_width;
    uint8_t                 active_speed;
    uint8_t                 phys_state;
};
variable description
state IBV_PORT_NOP
IBV_PORT_DOWN
IBV_PORT_INIT
IBV_PORT_ARMED
IBV_PORT_ACTIVE
IBV_PORT_ACTIVE_DEFER
max_mtu Maximum Transmission Unit (MTU) supported by port. Can be:
IBV_MTU_256
IBV_MTU_512
IBV_MTU_1024
IBV_MTU_2048
IBV_MTU_4096
active_mtu Actual MTU in use
gid_tbl_len Length of source global ID (GID) table
port_cap_flags Supported capabilities of this port. There are currently no enumerations/defines declared in verbs.h
max_msg_sz Maximum message size
bad_pkey_cntr Bad P_Key counter
qkey_viol_cntr Q_Key violation counter
pkey_tbl_len Length of partition table
lid First local identifier (LID) assigned to this port
sm_lid LID of subnet manager (SM)
lmc LID Mask control (used when multiple LIDs are assigned to port)
max_vl_num Maximum virtual lanes (VL)
sm_sl SM service level (SL)
subnet_timeout Subnet propagation delay
init_type_reply Type of initialization performed by SM
active_width Currently active link width
active_speed Currently active link speed
phys_state Physical port state

3.3.3 ibv_query_gid

int ibv_query_gid(struct ibv_context *context, uint8_t port_num, int index, union ibv_gid *gid)

Input Parameters:
context         struct ibv_context from ibv_open_device
port_num        physical port number (1 is first port)
index           which entry in the GID table to return (0 is first)
Output Parameters:
gid             union ibv_gid containing gid information
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_query_gid檢索端口全局標識符(GID)表中的條目。 每個端口由子網管理器(SM)分配至少一個GID。 GID是由全局唯一標識符(GUID)和由SM分配的前綴組成的有效IPv6地址。 GID [0]是唯一的,包含端口的GUID。
用戶應該分配一個聯合ibv_gid,將其傳遞給命令,並在成功返回時填寫它。 用戶有責任釋放這個聯合。
union ibv_gid定義如下:

union ibv_gid
{
    uint8_t         raw[16];
    struct
    {
        uint64_t    subnet_prefix;
        uint64_t    interface_id;
    } global;
}

3.3.4 ibv_query_pkey

int ibv_query_pkey(struct ibv_context *context, uint8_t port_num, int index, uint16_t *pkey)

Input Parameters:
context     struct ibv_context from ibv_open_device
port_num    physical port number (1 is first port)
index       which entry in the pkey table to return (0 is first)
Output Parameters:
pkey        desired pkey
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_query_pkey檢索端口分區密鑰(pkey)表中的條目。 每個端口由子網管理器(SM)分配至少一個pkey。 pkey標識端口所屬的分區。 pkey類似於以太網中的VLAN ID。
用戶將一個指針傳遞給一個將使用請求的pkey填充的uint16。 用戶有責任釋放這個uint16。

3.3.5 ibv_alloc_pd

struct ibv_pd *ibv_alloc_pd(struct ibv_context *context)

Input Parameters:
context struct ibv_context from ibv_open_device
Output Parameters:
none
Return Value:
Pointer to created protection domain or NULL on failure.

ibv_alloc_pd創建一個保護域(PD)。 PD限制可以通過哪些隊列對(QP)提供一定程度的保護以防止未經授權的訪問來訪問哪些存儲器區域。
用戶必須創建至少一個PD才能使用VPI verbs。

3.3.6 ibv_dealloc_pd

int ibv_dealloc_pd(struct ibv_pd *pd)

Input Parameters:
pd      struct ibv_pd from ibv_alloc_pd
Output Parameters:
none
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_dealloc_pd釋放保護域(PD)。 如果任何其他對象當前與指定的PD相關聯,則此命令將失敗。

3.3.7 ibv_create_cq

struct ibv_cq *ibv_create_cq(struct ibv_context *context, int cqe, void *cq_context, struct ibv_comp_channel *channel, int comp_vector)

Input Parameters:
context     struct ibv_context from ibv_open_device
cqe         Minimum number of entries CQ will support
cq_context  (Optional) User defined value returned with completion events
channel     (Optional) Completion channel
comp_vector (Optional) Completion vector
Output Parameters:
none
Return Value:
pointer to created CQ or NULL on failure.

ibv_create_cq創建一個完成隊列(CQ)。完成隊列保存完成隊列條目(CQE)。每個隊列對(QP)具有相關聯的發送和接收CQ。單個CQ可以共享用於發送和接收,並且可以跨多個QP共享。
參數cqe定義隊列的最小大小。隊列的實際大小可能大於指定的值。
參數cq_context是用戶定義的值。如果在創建CQ時指定,則在使用完成通道(CC)時,該值將作爲ibv_get_cq_event中的參數返回。
參數通道用於指定CC。 CQ只是一個沒有內置通知機制的隊列。當使用輪詢範例進行CQ處理時,不需要CC。用戶只需定期輪詢CQ。但是,如果您希望使用掛鉤範例,則需要CC。 CC是允許用戶通知新CQE在CQ上的機制。
參數comp_vector用於指定用於表示完成事件的完成向量。它必須是 >= 0和 < context->num_comp_vectors。

3.3.8 ibv_resize_cq

int ibv_resize_cq(struct ibv_cq *cq, int cqe)

Input Parameters:
cq      CQ to resize
cqe     Minimum number of entries CQ will support
Output Parameters:
none
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_resize_cq調整完成隊列(CQ)的大小。
參數cqe必須至少爲隊列中未決條目的數量。 隊列的實際大小可能大於指定的值。 當CQ調整大小時,CQ可以(或可能不)包含完成,可以在CQ工作期間調整大小。

3.3.9 ibv_destroy_cq

int ibv_destroy_cq(struct ibv_cq *cq)

Input Parameters:
cq      CQ to destroy
Output Parameters:
none
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_destroy_cq釋放一個完成隊列(CQ)。 如果存在與其相關聯的指定CQ的隊列對(QP),則此命令將失敗。

3.3.10 ibv_create_comp_channel

struct ibv_comp_channel *ibv_create_comp_channel(struct ibv_context *context)

Input Parameters:
context         struct ibv_context from ibv_open_device
Output Parameters:
none
Return Value:
pointer to created CC or NULL on failure.

ibv_create_comp_channel創建一個完成通道。 完成通道是當新的完成隊列事件(CQE)已經被放置在完成隊列(CQ)上時用戶接收通知的機制。

3.3.11 ibv_destroy_comp_channel

int ibv_destroy_comp_channel(struct ibv_comp_channel *channel)

Input Parameters:
channel         struct ibv_comp_channel from ibv_create_comp_channel
Output Parameters:
none
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_destroy_comp_channel釋放完成通道。 如果任何完成隊列(CQ)仍然與此完成通道相關聯,則此命令將失敗。

3.4 Protection Domain Operations

建立保護域(PD)後,您可以在該域內創建對象。 本節介紹PD上可用的操作。 這些包括註冊存儲器區域(MR),創建隊列對(QP)或共享接收隊列(SRQ)和地址句柄(AH)。

3.4.1 ibv_reg_mr

struct ibv_mr *ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, enum ibv_access_flags access)    

Input Parameters:
pd          protection domain, struct ibv_pd from ibv_alloc_pd
addr        memory base address
length      length of memory region in bytes
access      access flags
Output Parameters:
none
Return Value:
pointer to created memory region (MR) or NULL on failure.    

ibv_reg_mr註冊一個內存區域(MR),將其與保護域(PD)相關聯,併爲其分配本地和遠程密鑰(lkey,rkey)。 用到內存的所有VPI命令都需要通過該命令註冊內存。 相同的物理內存可以被映射到不同的MR,甚至根據用戶需求,允許不同的權限或PD被分配給相同的存儲器。
訪問標誌可能是按位或以下枚舉之一:

Enum Descript
IBV_ACCESS_LOCAL_WRITE 允許本地主機寫訪問
IBV_ACCESS_REMOTE_WRITE 允許遠程主機寫入訪問
IBV_ACCESS_REMOTE_READ 允許遠程主機讀取訪問權限
IBV_ACCESS_REMOTE_ATOMIC 允許遠程主機進行原子訪問
IBV_ACCESS_MW_BIND 允許此MR上的內存窗口

本地讀取訪問是隱含和自動的。
任何違反給定內存操作訪問權限的VPI操作都將失敗。 請注意,隊列對(QP)屬性還必須具有正確的權限,否則操作將失敗。
如果設置了IBV_ACCESS_REMOTE_WRITE或IBV_ACCESS_REMOTE_ATOMIC,則也必須設置IBV_ACCESS_LOCAL_WRITE。

結構體ibv_mr定義如下:

struct ibv_mr
{
    struct ibv_context      *context;
    struct ibv_pd           *pd;
    void                    *addr;
    size_t                  length;
    uint32_t                handle;
    uint32_t                lkey;
    uint32_t                rkey;
};

3.4.2 ibv_dereg_mr

int ibv_dereg_mr(struct ibv_mr *mr)

Input Parameters:
mr              struct ibv_mr from ibv_reg_mr
Output Parameters:
none
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_dereg_mr釋放內存區域(MR)。 如果任何存儲窗口(MW)仍然綁定到MR,操作將失敗。

3.4.3 ibv_create_qp

struct ibv_qp *ibv_create_qp(struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr)

Input Parameters:
pd                  struct ibv_pd from ibv_alloc_pd
qp_init_attr        initial attributes of queue pair
Output Parameters:
qp_init_attr        actual values are filled in
Return Value:
pointer to created queue pair (QP) or NULL on failure.

ibv_create_qp創建QP。 當創建QP時,將其置於RESET狀態。
struct qp_init_attr定義如下:

struct ibv_qp_init_attr
{
    void                *qp_context;
    struct ibv_cq       *send_cq;
    struct ibv_cq       *recv_cq;
    struct ibv_srq      *srq;
    struct ibv_qp_cap   cap;
    enum ibv_qp_type    qp_type;
    int                 sq_sig_all;
    struct ibv_xrc_domain *xrc_domain;
};
variable description example
qp_context (optional) user defined value associated with QP 未指定
send_cq send CQ. This must be created by the user prior to calling ibv_create_qp adapter.cq_
recv_cq receive CQ. This must be created by the user prior to calling ibv_create_qp. It may be the same as send_cq. adapter.cq_
srq (optional) shared receive queue. Only used for SRQ QP’s. 未指定
cap defined below. defined below.
qp_type must be one of the following:
IBV_QPT_RC = 2IBV_QPT_UC
IBV_QPT_UD
IBV_QPT_XRC
IBV_QPT_RAW_PACKET = 8
IBV_QPT_RAW_ETH = 8
IBV_QPT_RC
sq_sig_all If this value is set to 1, all send requests (WR) will generate completion queue events (CQE). If this value is set to 0, only WRs that are flagged will generate CQE’s (see ibv_post_send). 未指定
xrc_domain (Optional) Only used for XRC operations. 未指定

struct ibv_qp_cap
{
uint32_t max_send_wr;
uint32_t max_recv_wr;
uint32_t max_send_sge;
uint32_t max_recv_sge;
uint32_t max_inline_data;
};

variable description example
max_send_wr Maximum number of outstanding send requests in the send queue MAX_CONCURRENT_WRITES(1000)
max_recv_wr Maximum number of outstanding receive requests (buffers) in the receive queue. MAX_CONCURRENT_WRITES(1000)
max_send_sge Maximum number of scatter/gather elements (SGE) in a WR on the send queue. 1
max_recv_sge Maximum number of SGEs in a WR on the receive queue. 1
max_inline_data Maximum size in bytes of inline data on the send queue. 未指定

3.4.4 ibv_destroy_qp

int ibv_destroy_qp(struct ibv_qp *qp)

Input Parameters:
qp              struct ibv_qp from ibv_create_qp
Output Parameters:
none
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_destroy_qp釋放隊列對(QP)。

3.4.5 ibv_create_srq

struct ibv_srq *ibv_create_srq(struct ibv_pd *pd, struct ibv_srq_init_attr *srq_init_attr)

Input Parameters:
pd              The protection domain associated with the shared receive queue (SRQ)
srq_init_attr   A list of initial attributes required to create the SRQ
Output Parameters:
ibv_srq__attr   Actual values of the struct are set
Return Value:
A pointer to the created SRQ or NULL on failure

ibv_create_srq創建一個共享接收隊列(SRQ)。 讀取srq_attr-> max_wr和srq_attr-> max_sge以確定所需的SRQ大小,並將其設置爲返回時分配的實際值。 如果ibv_create_srq成功,那麼max_wr和max_sge將至少與請求的值一樣大。
struct ibv_srq定義如下:

struct ibv_srq {
    struct ibv_context      *context;       struct ibv_context from ibv_open_device
    void                    *srq_context;
    struct ibv_pd           *pd;            Protection domain
    uint32_t                handle;
    pthread_mutex_t         mutex;
    pthread_cond_t          cond;
    uint32_t                events_completed;
}

struct ibv_srq_init_attr定義如下:

struct ibv_srq_init_attr
{
    void *srq_context;
    struct ibv_srq_attr attr;
};

— | —
srq_context | struct ibv_context from ibv_open_device
attr | An ibv_srq_attr struct defined as follows

struct ibv_srq_attr定義如下:

struct ibv_srq_attr
{
    uint32_t    max_wr;
    uint32_t    max_sge;
    uint32_t    srq_limit;
};

— | —
max_wr | Requested maximum number of outstanding WRs in the SRQ
max_sge | Requested number of scatter elements per WR
srq_limit | The limit value of the SRQ (irrelevant for ibv_create_srq)

3.4.6 ibv_modify_srq

int ibv_modify_srq (struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, int srq_attr_mask)

Input Parameters:
srq             The SRQ to modify
srq_attr        Specifies the SRQ to modify (input)/the current values of the selected SRQ attributes are returned (output)
srq_attr_mask   A bit-mask used to specify which SRQ attributes are being modified
Output Parameters:
srq_attr        The struct ibv_srq_attr is returned with the updated values
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_modify_srq使用srq_attr中的屬性值根據掩碼srq_attr_mask修改SRQ srq的屬性。 srq_attr是ibv_create_srq下面定義的ibv_srq_attr結構。 參數srq_attr_mask指定要修改的SRQ屬性。 它是一個或多個標誌的0或按位OR:

— | —
IBV_SRQ_MAX_WR | Resize the SRQ
IBV_SRQ_LIMIT | Set the SRQ limit

如果要修改的任何屬性無效,則不會修改任何屬性。 此外,並非所有設備都支持調整SRQ的大小。 要檢查設備是否支持調整大小,請檢查設備能力標誌中是否設置了IBV_DEVICE_SRQ_RESIZE位。
一旦SRQ中的WR數降到SRQ限制以下,修改SRQ限制就會使SRQ產生一個IBV_EVENT_SRQ_LIMIT_REACHED’低水印’異步事件。

3.4.7 ibv_destroy_srq

3.4.8 ibv_open_xrc_domain

3.4.9 ibv_create_rc_srq

3.4.10 ibv_close_xrc_domain

3.4.11 ibv_create_xrc_rcv_qp

3.4.12 ibv_modify_xrc_rcv_qp

3.4.13 ibv_reg_xrc_rcv_qp

3.4.14 ibv_unreg_xrc_rcv_qp

3.4.15 ibv_create_ah

3.4.16 ibv_destroy_ah

3.5 Queue Pair Bringup (ibv_modify_qp)

3.5.1 ibv_modify_qp

int ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, enum ibv_qp_attr_mask attr_mask)

struct ibv_qp_attr
{
    enum ibv_qp_state qp_state;
    enum ibv_qp_state cur_qp_state;
    enum ibv_mtu path_mtu;
    enum ibv_mig_state path_mig_state;
    uint32_t qkey;
    uint32_t rq_psn;
    uint32_t sq_psn;
    uint32_t dest_qp_num;
    int qp_access_flags;
    struct ibv_qp_cap cap;
    struct ibv_ah_attr ah_atpsntr;
    struct ibv_ah_attr alt_ah_attr;
    uint16_t pkey_index;
    uint16_t alt_pkey_index;
    uint8_t en_sqd_async_notify;
    uint8_t sq_draining;
    uint8_t max_rd_atomic;
    uint8_t max_dest_rd_atomic;
    uint8_t min_rnr_timer;
    uint8_t port_num;
    uint8_t timeout;
    uint8_t retry_cnt;
    uint8_t rnr_retry;
    uint8_t alt_port_num;
    uint8_t alt_timeout;
};

IBV_QP_STATE
IBV_QP_CUR_STATE
IBV_QP_EN_SQD_ASYNC_NOTIFY
IBV_QP_ACCESS_FLAGS
IBV_QP_PKEY_INDEX
IBV_QP_PORT
IBV_QP_QKEY
IBV_QP_AV
IBV_QP_PATH_MTU
IBV_QP_TIMEOUT
IBV_QP_RETRY_CNT
IBV_QP_RNR_RETRY
IBV_QP_RQ_PSN
IBV_QP_MAX_QP_RD_ATOMIC
IBV_QP_ALT_PATH
IBV_QP_MIN_RNR_TIMER
IBV_QP_SQ_PSN
IBV_QP_MAX_DEST_RD_ATOMIC
IBV_QP_PATH_MIG_STATE
IBV_QP_CAP
IBV_QP_DEST_QPN

3.5.2 RESET to INIT

3.5.3 INIT to RTR

3.5.4 RTR to RTS

3.6 Active Queue Pair Operations

3.6.1 ibv_query_qp

3.6.2 ibv_query_srq

3.6.3 ibv_query_xrc_rcv_qp

3.6.4 ibv_post_recv

int ibv_post_recv(struct ibv_qp *qp, struct ibv_recv_wr *wr, struct ibv_recv_wr **bad_wr)

Input Parameters:

qp struct ibv_qp from ibv_create_qp
wr first work request (WR) containing receive buffers

Output Parameters:
bad_wr pointer to first rejected WR

Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

struct ibv_recv_wr
{
    uint64_t wr_id;             //user assigned work request ID
    struct ibv_recv_wr *next;   //pointer to next WR, NULL if last one.
    struct ibv_sge *sg_list;    //scatter array for this WR
    int num_sge;                //number of entries in sg_list
};

struct ibv_sge
{
    uint64_t addr;              //address of buffer
    uint32_t length;            //length of buffer
    uint32_t lkey;              //local key (lkey) of buffer from ibv_reg_mr
};

ibv_post_recv將一系列WRs發佈到QP的接收隊列。應將至少一個接收緩衝區發佈到接收隊列,以將QP轉換爲RTR。 隨着遠程執行發送、立即發送和使用即時操作的RDMA寫入、接收緩衝區被消耗。 接收緩衝區不用於其他RDMA操作。 WR列表的處理在第一個錯誤上停止,並且在bad_wr中返回指向違規WR的指針。

3.6.5 ibv_post_send

int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr, struct ibv_send_wr **bad_wr)

Input Parameters:
qp      struct ibv_qp from ibv_create_qp
Output Parameters:
bad_wr  pointer to first rejected WR
Return Value:
0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

ibv_post_send將一個WR list鏈接到隊列對(QP)發送隊列。 此操作用於啓動所有通信,包括RDMA操作。 WR列表的處理在第一個錯誤上停止,並且在bad_wr中返回指向違規WR的指針。
用戶不應該更改或銷燬與WR相關聯的AH,直到請求完全執行,並從對應的完成隊列(CQ)中檢索到完成隊列條目(CQE)以避免意外的行爲。
WR完全執行後才能安全地重複使用WR緩衝區,並從對應的CQ中檢索出WCE。 但是,如果設置了IBV_SEND_INLINE標誌,緩衝區可以在調用返回後立即重新使用。
struct ibv_send_wr定義如下:

struct ibv_send_wr
{
    uint64_t wr_id;
    struct ibv_send_wr *next;
    struct ibv_sge *sg_list;
    int num_sge;
    enum ibv_wr_opcode opcode;
    enum ibv_send_flags send_flags;
    uint32_t imm_data;/* network byte order */
    union
    {
        struct
        {
            uint64_t remote_addr;
            uint32_t rkey;
        } rdma;
        struct
        {
            uint64_t remote_addr;
            uint64_t compare_add;
            uint64_t swap;
            uint32_t rkey;
        } atomic;
        struct
        {
            struct ibv_ah *ah;
            uint32_t remote_qpn;
            uint32_t remote_qkey;
        } ud;
    } wr;
    uint32_t xrc_remote_srq_num;
};
variable description
wr_id user assigned work request ID
next pointer to next WR, NULL if last one.
sg_list scatter/gather array for this WR
num_sge number of entries in sg_list
opcode IBV_WR_RDMA_WRITE
IBV_WR_RDMA_WRITE_WITH_IMM
IBV_WR_SEND
IBV_WR_SEND_WITH_IMM
IBV_WR_RDMA_READ
IBV_WR_ATOMIC_CMP_AND_SWP
IBV_WR_ATOMIC_FETCH_AND_ADD
send_flags (optional) - this is a bitwise OR of the flags. See the details below.
imm_data immediate data to send in network byte order
remote_addr remote virtual address for RDMA/atomic operations
rkey remote key (from ibv_reg_mr on remote) for RDMA/atomic operations
compare_add compare value for compare and swap operation
swap swap value
ah address handle (AH) for datagram operations
remote_qpn remote QP number for datagram operations
remote_qkey Qkey for datagram operations
xrc_remote_srq_num shared receive queue (SRQ) number for the destination extended reliable connection (XRC). Only used for XRC operations.
send flags description
IBV_SEND_FENCE set fence indicator
IBV_SEND_SIGNALED send completion event for this WR. Only meaningful for QPs that had the sq_sig_all set to 0
發送此WR的完成事件。 只對sq_sig_all設置爲0的QP有意義
IBV_SEND_SEND_SOLICITED set solicited event indicator
IBV_SEND_INLINE send data in sge_list as inline data.

3.6.6 ibv_post_srq_recv

3.6.7 ibv_req_notify_cq

int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only)

3.6.8 ibv_get_cq_event

3.6.9 ibv_ack_cq_events

void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents)
Input Parameters:
cq          struct ibv_cq from ibv_create_cq
nevents     number of events to acknowledge (1...n)
Output Parameters:
None
Return Value:
None

ibv_ack_cq_events確認從ibv_get_cq_event接收到的事件。 雖然從ibv_get_cq_event接收到的每個通知只算一個事件,但用戶可以通過單次調用ibv_ack_cq_events來確認多個事件。 要確認的事件數量在nevents中傳遞,應至少爲1個。由於此操作需要互斥體,因此在某個調用中確認多個事件可能會提供更好的性能。
有關其他詳細信息,請參閱ibv_get_cq_event。

3.6.10 ibv_poll_cq

int ibv_poll_cq(struct ibv_cq *cq, int num_entries, struct ibv_wc *wc)
Input Parameters:
cq              struct ibv_cq from ibv_create_cq
num_entries     maximum number of completion queue entries (CQE) to return
Output Parameters:
wc              CQE array
Return Value:
Number of CQEs in array wc or -1 on error

ibv_poll_cq從完成隊列(CQ)中檢索CQE。 用戶應該分配一個struct ibv_wc的數組,並將其傳遞給wc中的調用。 wc中可用的條目數應該以num_entries的形式傳遞。 釋放這個內存是用戶的責任。
實際檢索的CQE數量作爲返回值。
定期檢查CQ以防止超限。 在超載的情況下,CQ將被關閉,並且將發送異步事件IBV_EVENT_CQ_ERR。
struct ibv_wc定義如下:

struct ibv_wc
{
    uint64_t wr_id;
    enum ibv_wc_status status;
    enum ibv_wc_opcode opcode;
    uint32_t vendor_err;
    uint32_t byte_len;
    uint32_t imm_data;/* network byte order */
    uint32_t qp_num;
    uint32_t src_qp;
    enum ibv_wc_flags wc_flags;
    uint16_t pkey_index;
    uint16_t slid;
    uint8_t sl;
    uint8_t dlid_path_bits;
};
variable 描述
wr_id user specified work request id as given in ibv_post_send or ibv_post_recv
status IBV_WC_SUCCESS
IBV_WC_LOC_LEN_ERR
IBV_WC_LOC_QP_OP_ERR
IBV_WC_LOC_EEC_OP_ERR
IBV_WC_LOC_PROT_ERR
IBV_WC_WR_FLUSH_ERR
IBV_WC_MW_BIND_ERR
IBV_WC_BAD_RESP_ERR
IBV_WC_LOC_ACCESS_ERR
IBV_WC_REM_INV_REQ_ERR
IBV_WC_REM_ACCESS_ERR
IBV_WC_REM_OP_ERR
IBV_WC_RETRY_EXC_ERR
IBV_WC_RNR_RETRY_EXC_ERR
IBV_WC_LOC_RDD_VIOL_ERR
IBV_WC_REM_INV_RD_REQ_ERR
IBV_WC_REM_ABORT_ERR
IBV_WC_INV_EECN_ERR
IBV_WC_INV_EEC_STATE_ERR
IBV_WC_FATAL_ERR
IBV_WC_RESP_TIMEOUT_ERR
IBV_WC_GENERAL_ERR
opcode IBV_WC_SEND,
IBV_WC_RDMA_WRITE,
IBV_WC_RDMA_READ,
IBV_WC_COMP_SWAP,
IBV_WC_FETCH_ADD,
IBV_WC_BIND_MW,
IBV_WC_RECV= 1 << 7,
IBV_WC_RECV_RDMA_WITH_IMM
vendor_err vendor specific error
byte_len number of bytes transferred
imm_data immediate data
qp_num local queue pair (QP) number
src_qp remote QP number
wc_flags IBV_WC_GRH global route header (GRH) is present in UD packet
IBV_WC_WITH_IMM immediate data value is valid
pkey_index index of pkey (valid only for GSI QPs)
slid source local identifier (LID)
sl service level (SL)
dlid_path_bits destination LID path bits

3.6.11 ibv_init_ah_from_wc

3.6.12 ibv_create_ah_from_wc

3.6.13 ibv_attach_mcast

3.6.14 ibv_detach_mcast

3.7 Event Handing Operations

3.7.1 ibv_get_async_event

3.7.2 ibv_ack_async_enentibv_reg_mr

3.7.3 ibv_event_type_str

3.8 Experimental APIs

3.8.1 ibv_exp_query_device

3.8.2 ibv_exp_create_qp

3.8.3 ibv_exp_post_send

7 IBV Verbs編程示例

7.1 使用IBV Verbs的RDMA_RC示例概要

以下是編程示例中的函數的概要,按照它們的調用順序。

代碼如 RDMA_RC_example.c

解析命令行。 用戶可以設置測試的TCP端口,設備名稱和設備端口。 如果設置,這些值將覆蓋config中的默認值。 最後一個參數是服務器名稱。 如果設置了服務器名稱,則指定要連接的服務器,因此將程序放入客戶端模式。 否則程序處於服務器模式。

  1. 調用print_config打印輸出配置信息。
  2. 調用resources_init清除資源結構。
  3. 調用resources_create
    1. 調用sock_connect使用TCP套接字與對方進行連接。
      1. 如果是客戶端,則解析服務器的DNS地址併發起連接。
      2. 如果是服務器,則在指定端口上偵聽傳入連接。
    2. 獲取設備列表,找到我們想要的設備,並打開它。
    3. 釋放設備列表。
    4. 獲取端口信息。
    5. 創建一個PD。
    6. 創建一個CQ。
    7. 分配一個緩衝區,初始化並註冊。
    8. 創建一個QP。
  4. 調用connect_qp
    1. 調用sock_sync_data來在服務器和客戶端之間交換地址信息,使用由sock_connect創建的TCP套接字,在客戶端和服務器之間同步給定的一組數據。 由於這個功能是阻塞的,所以也使用dummy data來同步客戶端和服務器的時序。
    2. 調用modify_qp_to_init 將QP轉換到INIT狀態。
    3. 如果是客戶端,則調用post_receive
      1. 爲接收緩衝區準備一個 scatter/gather 實體。
      2. 準備一個RR。
      3. post這個RR。
    4. 調用modify_qp_to_rtr 將QP轉換到RTR狀態。
    5. 調用modify_qp_to_rts 將QP轉換到RTS狀態。
    6. 調用sock_sync_data來同步客戶端<->服務器的時序。
  5. 如果在服務器模式下,請使用 IBV_WR_SEND 操作調用post_send
    1. 爲要發送的數據(或在RDMA讀取情況下接收的數據)準備分散/收集條目。
    2. 創建SR。 請注意,IBV_SEND_SIGNALED是多餘的。
    3. 如果是RDMA操作,請設置地址和密鑰。
    4. post SR。
  6. 調用poll_completion。 請注意,服務器端期望從SEND請求完成,並且客戶端期望RECEIVE完成。
    1. 輪詢CQ直到找到條目或達到MAX_POLL_CQ_TIMEOUT毫秒。
  7. 如果在客戶端模式下,則顯示通過RECEIVE操作收到的消息。
  8. 如果在服務器模式下,則使用新的消息填充緩衝區。
  9. 同步 客戶端<->服務器 的時序。
  10. 在這一點上,服務器直接進入下一個時序同步。 所有RDMA操作都由客戶端完成。
  11. 客戶端操作
    1. 使用IBV_WR_RDMA_READ調用post_send,執行服務器緩衝區的RDMA讀取。
    2. 調用poll_completion
    3. 顯示服務器的消息。
    4. 使用新消息設置發送緩衝區。
    5. 使用IBV_WR_RDMA_WRITE調用post_send以執行服務器緩衝區的RDMA寫入。
    6. 調用poll_completion
  12. 同步客戶端< - >服務器的時序。
  13. 如果服務器模式,顯示緩衝區,證明RDMA已經寫入。
  14. 調用resources_destroy release/free/deallocate 資源結構中的所有項目。。
  15. 釋放設備名稱字符串。
  16. 完成。
發佈了45 篇原創文章 · 獲贊 61 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章