DPDK(Data Plane Development Kit)是數(shù)據(jù)平面開發(fā)工具包,由用于加速在各種CPU架構上運行的數(shù)據(jù)包處理的庫組成。


在Linux上捕獲數(shù)據(jù)包有多種方式,常見的有l(wèi)ibpcap,pf-ring等。DPDK以高性能著稱,想必相比傳統(tǒng)的數(shù)據(jù)包捕獲方式,一定有其獨到之處。


本文主要就DPDK所使用的技術點進行宏觀的說明,并將其與libpcap,pf-ring進行對比,若有寫的不對的地方請幫忙指出。


參考文檔:

[1]絕對干貨!初學者也能看懂的DPDK解析

[2]Linux 設備驅動之 UIO 機制(基本概念)

[3]PF_RING學習筆記


若出現(xiàn)侵權請聯(lián)系作者刪除。


1.DPDK 技術特點


傳統(tǒng)的數(shù)據(jù)包捕獲瓶頸往往在于Linux Kernel,數(shù)據(jù)流需要經(jīng)過Linux Kernel,就會帶來Kernel Spcae和User Space數(shù)據(jù)拷貝的消耗;系統(tǒng)調(diào)用的消耗;中斷處理的消耗等。


DPDK針對Linux Kernel傳統(tǒng)的數(shù)據(jù)包捕獲模式的問題,進行了一定程度的優(yōu)化。DPDK的優(yōu)化可以概括為:


UIO+mmap 實現(xiàn)零拷貝(zero copy)

UIO+PMD 減少中斷和CPU上下文切換

HugePages 減少TLB miss

其他代碼優(yōu)化

2.UIO


2.1 UIO簡介


UIO(Userspace I/O)是運行在用戶空間的I/O技術。Linux系統(tǒng)中一般的驅動設備都是運行在內(nèi)核空間,而在用戶空間用應用程序調(diào)用即可,而UIO則是將驅動的很少一部分運行在內(nèi)核空間,而在用戶空間實現(xiàn)驅動的絕大多數(shù)功能。



圖片引自百度百科

一個設備驅動的主要任務有兩個:


存取設備的內(nèi)存

處理設備產(chǎn)生的中斷

如上圖所示,對于存取設備的內(nèi)存 ,UIO 核心實現(xiàn)了mmap();對于處理設備產(chǎn)生的中斷,內(nèi)核空間有一小部分代碼用處理中斷,用戶空間通過read()接口/dev/uioX來讀取中斷。


2.2 DPDK UIO機制


采用Linux提供UIO機制,可以旁路Kernel,將所有報文處理的工作在用戶空間完成。



圖片引自參考文檔[1]

如上圖,左邊是傳統(tǒng)的數(shù)據(jù)包獲取方式,路徑為:

網(wǎng)卡 -> Kernel驅動 -> Kernel TCP/IP協(xié)議棧 -> Socket接口 -> 業(yè)務

右邊是DPDK的方式,基于UIO。數(shù)據(jù)路徑為:

網(wǎng)卡 -> DPDK輪詢模式-> DPDK基礎庫 -> 業(yè)務


2.3 DPDK 零拷貝(Zero Copy)


通過UIO+mmap 實現(xiàn)數(shù)據(jù)零拷貝(zero copy)是DPDK的特點之一。那么常規(guī)的Linux Kernel(libpcap)以及pf-ring處理數(shù)據(jù)包的流程要進行幾次數(shù)據(jù)拷貝呢?


libpcap

libpcap采用的是傳統(tǒng)的數(shù)據(jù)包獲取方式,如上圖左邊路徑。

網(wǎng)卡接收到數(shù)據(jù)包后,第一步需要把數(shù)據(jù)從網(wǎng)卡拷貝到主存(RX buffer)中。但是在這個拷貝的過程中使用了DMA(Direct Memory Access)技術。DMA 傳輸將數(shù)據(jù)從一個地址空間復制到另外一個地址空間。由CPU 初始化這個傳輸動作,傳輸動作本身是由 DMA 控制器來實行和完成,CPU是不需要參與,也不會產(chǎn)生CPU資源消耗。因此這個第一步的拷貝可以忽略。

第二步,Kernel會將網(wǎng)卡通過DMA傳輸進入主存(RX buffer)的內(nèi)容拷貝一份進行處理,這里進行了一次數(shù)據(jù)拷貝。

第三步,由于內(nèi)核空間和用戶空間的內(nèi)存是不共享的,Kernel會將數(shù)據(jù)包內(nèi)容再進行一次拷貝用于用戶空間使用。

綜上,傳統(tǒng)的數(shù)據(jù)包捕獲方式(libpcap)會進行兩次數(shù)據(jù)包拷貝。


pf-rfing

pf-ring采用mmap()將傳統(tǒng)的兩次拷貝減少至一次拷貝。

第一步,同樣使用DMA技術,把數(shù)據(jù)從網(wǎng)卡拷貝到主存(RX buffer)中。

第二步,pf-ring會將網(wǎng)卡通過DMA傳輸進入主存(RX buffer)的內(nèi)容拷貝一份放入環(huán)形緩沖區(qū)中(ring)中,這里進行了一次數(shù)據(jù)拷貝。

第三步,使用mmap()將環(huán)形緩沖區(qū)映射至用戶空間,用戶空間可以直接訪問這個環(huán)形緩沖區(qū)中的數(shù)據(jù)。


pf-ring zc

pf-ring zc(zero copy)更是將pf-ring的一次拷貝也省去,達到了零拷貝的目的,具體的:

第一步,使用DMA技術,把數(shù)據(jù)從網(wǎng)卡拷貝到主存(RX buffer)中。

第二步,使用mmap()直接將RX buffer的數(shù)據(jù)映射到用戶用戶空間,使用戶空間可以直接訪問RX buffer的數(shù)據(jù)。

下圖非常清晰地展示了pf-ring zc實現(xiàn)零拷貝的過程:



圖片引自參考文檔[3]

DPDK

DPDK實現(xiàn)零拷貝的方式與pf-ring zc類似,首先通過DMA將網(wǎng)卡數(shù)據(jù)拷貝至主存(RX buffer);隨后使用mmap()直接將RX buffer的數(shù)據(jù)映射到用戶用戶空間,使用戶空間可以直接訪問RX buffer的數(shù)據(jù),以此實現(xiàn)了零拷貝。


由上述可以看出,pf-ring zc和dpdk均可以實現(xiàn)數(shù)據(jù)包的零拷貝,兩者均旁路了內(nèi)核,但是實現(xiàn)原理略有不同。pf-ring zc通過zc驅動(也在應用層)接管數(shù)據(jù)包,dpdk基于UIO實現(xiàn)。