目錄
前文列表
《DPDK — 安裝部署》
《DPDK — 數據平面開發技術》
DPDK 架構
內核態模塊:
- IGB_UIO:
- KNI
用戶態函數庫以及網卡驅動程序:
- 用戶態輪詢模式的網卡驅動程序(PMD Driver)
- 核心部件庫(Core Libraries)
- 操作系統平台相關模塊(Platform)
- QoS 庫
- 報文轉發分類算法庫(Classify)
用戶應用程序可以應用以上函數庫以及驅動支持,來實現完全內核旁路的數據面轉發應用程序,例如:OVS-DPDK。
- EAL(Environment Abstraction Layer,環境抽象層):為應用提供了一個通用接口,隱藏了與底層庫與設備打交道的相關細節。EAL 實現了 DPDK 運行的初始化工作,基於大頁表的內存分配,多核親緣性設置,原子和鎖操作,並將 PCI 設備地址映射到用戶空間,方便應用程序訪問。
- Buffer Manager API:通過預先從 EAL 上分配固定大小的多個內存對象,避免了在運行過程中動態進行內存分配和回收,以此來提高效率,用於數據包 Buffer 的管理。
- Queue/Ring Manager API:以高效的方式實現了無鎖的 FIFO 環形隊列,適用於一個生產者多個消費者、一個消費者多個生產者模型。支持批量無鎖操作,可避免鎖沖突導致的等待。
- Packet Flow Classification API:通過 Intel SSE 基於多元組的方式實現了高效的 HASH 算法,以便快速對數據包進行分類處理。該 API 一般用於路由查找過程中的最長前綴匹配。此外,安全產品場景中,可以根據 DataFlow 五元組來標記不同的用戶。
- PMD(Poll Mode Library):則實現了 Intel 1GbE、10GbE 和 40GbE 網卡下基於輪詢收發包的工作模式,大大加速網卡收發包性能。
內核態模塊
IGB_UIO
《DPDK — IGB_UIO,與 UIO Framework 進行交互的內核模塊》
KNI
KNI(Kernel NIC Interface,內核網卡接口),是 DPDK 允許用戶態和內核態交換報文的解決方案,模擬了一個虛擬的網口,提供 DPDK 應用程序和 Linux 內核之間通訊沒接。即 KNI 接口允許報文從用戶態接收后轉發到 Linux 內核協議棧中去。
雖然 DPDK 的高速轉發性能很出色,但是也有自己的一些缺點,比如沒有標准協議棧就是其中之一,當然也可能當時設計時就將沒有將協議棧考慮進去,畢竟協議棧需要將報文轉發處理,可能會使處理報文的能力大大降低。
上圖是 KNI 的 mbuf 的使用流程,也可以看出報文的流向,因為報文在代碼中其實就是一個個內存指針。其中 rx_q 右邊是用戶態,左邊是內核態。最后通過調用 netif_rx 將報文送入 Linux 內核協議棧,這其中需要將 DPDK 的 mbuf 轉換成標准的 skb_buf 結構體。當 Linux 內核向 KNI 端口發送報文時,調用回調函數 kni_net_tx,然后報文經過轉換之后發送到端口上。
PMD
DPDK Lib(核心部件庫)
核心部件庫(Core Libraries)是 DPDK 面向用戶態協議棧應用程序員開發的模塊。
-
EAL(Environment Abstraction Layer,環境抽象層):對 DPDK 的運行環境(e.g. Linux 操作系統)進行初始化,包括:HugePage 內存分配、內存/緩沖區/隊列分配、原子性無鎖操作、NUMA 親和性、CPU 綁定等,並通過 UIO 或 VFIO 技術將 PCI/PCIe 設備地址映射到用戶態,方便了用戶態的 DPDK 應用程序調用。同時為應用程序提供了一個通用接口,隱藏了其與底層庫以及設備打交道的相關細節。
-
MALLOC(堆內存管理組件):為 DPDK 應用程序提供從 HugePage 內分配堆內存的接口。當需要為 SKB(Socket Buffer,本質是若干個數據包的緩存區)分配大量的小塊內存時(如:分配用於存儲 Buffer descriptor table 中每個表項指針的內存)可以調用該接口。由於堆內存是從 HugePage 內存分配的,所以可以減少 TLB 缺頁。
注:堆,是由開發人員主動分配和釋放的存儲空間, 若開發人員不釋放,則程序結束時由 OS 回收,分配方式類似於鏈表;與堆不同,棧,是由操作系統自動分配和釋放的存儲空間 ,用於存放函數的參數值、局部變量等,其操作方式類似於數據結構中的棧。
-
MBUF(網絡報文緩存塊管理組件):為 DPDK 應用程序提供創建和釋放用於存儲數據報文信息的緩存塊的接口。提供了兩種類型的 MBUF,一種用於存儲一般信息,一種用於存儲實際的報文數據。這些 MBUF 存儲在一個內存池中。
-
MEMPOOL(內存池管理組件):為 DPDK 應用程序和其它組件提供分配內存池的接口,內存池是一個由固定大小的多個內存塊組成的內存容器,可用於存儲不同的對像實體,如:數據報文緩存塊等。內存池由內存池的名稱(一個字符串)進行唯一標識,它由一個 Ring 緩沖區和一組本地緩存隊列組成,每個 CPU Core 優先從自身的緩存隊列中分配內存塊,當本地緩存隊列減少到一定程度時,開始從內存環緩沖區中申請內存塊來進行補充。
-
RING(環緩沖區管理組件):為 DPDK 應用程序和其它組件提供一個無鎖的多生產者多消費者 FIFO 隊列。
NOTE:DPDK 基於 Linux 內核的無鎖環形緩沖 kfifo 實現了一套自己的無鎖機制。支持單生產者入列/單消費者出列和多生產者入列/多消費者出列操作,在數據傳輸的時候,降低性能的同時還能保證數據的同步。
- TIMER(定時器組件):提供一些異步周期執行的接口(也可以只執行一次),可以指定某個函數在規定時間內的異步執行,就像 LIBC 中的 timer 定時器。但是這里的定時器需要 DPDK 應用程序在主循環中周期內調用
rte_timer_manage
來使能定時器,使用起來不那么方便。TIMER 的時間參考來自 EAL 層提供的時間接口。
注:除了以上六個核心組件外,DPDK 還提供以下功能:
- 以太網輪詢模式驅動(PMD)架構:把以太網驅動從內核移到應用層,采用同步輪詢機制而不是內核態的異步中斷機制來提高報文的接收和發送效率。
- 報文轉發算法支持:Hash 庫和 LPM 庫為報文轉發算法提供支持。
- 網絡協議定義和相關宏定義:基於 FreeBSD IP 協議棧的相關定義,如:TCP、UDP、SCTP 等協議頭定義。
- 報文 QoS 調度庫:支持隨機早檢測、流量整形、嚴格優先級和加權隨機循環優先級調度等相關 QoS 功能。
- 內核網絡接口庫(KNI):提供一種 DPDK 應用程序與內核協議棧的通信的方法,類似 Linux 的 TUN/TAP 接口,但比 TUN/TAP 接口效率高。每個物理網口可以虛擬出多個 KNI 接口。
組件代碼
注:
- RTE:Run-Time Environment
- EAL:Environment Abstraction Layer
- PMD:Poll-Mode Driver
核心部件庫對應的 DPDK 核心組件實現:
-
Memory Manager(librte_malloc,堆內存管理器):提供一組 API,用於從 HugePages 內存創建的 memzones 中分配內存,而不是在堆中分配。這有助於改善 Linux 用戶空間環境下典型的從堆中大量分配 4KB 頁面而容易引起 TLB 不命中。
-
Memory Pool Manager(librte_mempool,內存池管理器):內存池管理器負責分配的內存中的 Pool 對象。Pool 由名稱唯一標識,並使用一個 Ring 來存儲空閑對象。它提供了其他一些可選的服務,例如:每個 CPU Core 的對象緩存和對齊方式幫助,以確保將填充的對象在所有內存通道上得到均勻分布。
-
Ring Manager(librte_ring,環形隊列管理器):在一個大小有限的頁表中,Ring 數據結構提供了一個無鎖的多生產者-多消費者 FIFO API。相較於無鎖隊列,它有一些的優勢,如:更容易實現,適應於大容量操作,而且速度更快。 一個 Ring 可以在 Memory Pool Manager 中被使用,也可以用於不同 CPU Core 或 Processor 之間作為通用的通信機制。
-
Network Packet Buffer Management(librte_mbuf,網絡報文緩沖區管理):提供一組 API,用於分配、釋放和操作 MBUFs(數據報文緩沖區),DPDK 應用程序中可以使用這些緩存區來存儲消息以及報文數據。
-
Timer Manager(librte_timer,定時器管理):為 DPDK 應用程序的執行單元提供了定時服務,支持以異步的方式執行函數。定時器可以設置周期調用,也可以設置為只調用一次。DPDK 應用程序可以使用 EAL 提供的 HPET 接口來獲取高精度時鍾的引用,並且能在每個 Core 上根據需要進行初始化。
代碼目錄:
平台相關模塊
平台相關模塊(Platform)包括 KNI、POWER(能耗管理)以及 IVSHMEM 接口。
-
KNI:主要通過 Linux 內核中的 kni.ko 模塊將數據報文從用戶態傳遞給內核態協議棧處理,以便常規的用戶進程(e.g. Container)可以使用 Linux 內核協議棧傳統的 Socket 接口對相關報文進行處理。
-
POWER:提供了一些 API,讓 DPDK 應用程序可以根據收包速率動態調整 CPU 頻率或讓 CPU 進入不同的休眠狀態。
-
IVSHMEM:模塊提供了虛擬機與虛擬機之間,或者虛擬機與主機之間的零拷貝共享內存機制。當 DPDK 應用程序運行時,IVSHMEM 模塊會調用 Core Libraries 的 API,把幾個 HugePage 內存映射為一個 IVSHMEM 設備池,並通過參數傳遞給 QEMU,這樣,就實現了虛擬機之間的零拷貝內存共享。
Classify 庫
支持精確匹配(Exact Match)、最長匹配(LPM)和通配符匹配(ACL)數據報文,並提供常用的包處理的查表操作。
QoS 庫
提供網絡服務質量相關的組件,如:限速(Meter)和調度(Scheduler)。