前言
說到互聯(lián)網(wǎng),大家很容易想到的有 CPU、服務(wù)器、操作系統(tǒng)、應(yīng)用程序(App)、小程序、網(wǎng)頁(html)等。然而,還有一個要素是很容易被忽略的,卻是最重要的,那就是網(wǎng)卡。如果沒有網(wǎng)卡,那么所有的主機將會是孤立的,沒法實現(xiàn)相互間通信,也就不存在互聯(lián)網(wǎng)了。兩臺主機之間要實現(xiàn)通信,互相收發(fā)報文,最底層的基礎(chǔ)設(shè)施,除了傳輸鏈路(光纖、網(wǎng)線等),就是安裝在主機上的網(wǎng)卡了,它將主機上應(yīng)用軟件產(chǎn)生的數(shù)據(jù)打包,然后從物理鏈路上發(fā)送出去,同理,它還可以從物理鏈路上接收報文,送往主機上的應(yīng)用程序。
在這篇文章中,你將會了解到什么是中斷,什么是 PCIe,什么是 uio,什么是 igb_uio,什么是 pmd,什么是 DPDK 等一系列與網(wǎng)卡相關(guān)的概念及網(wǎng)卡工作的原理。

物理網(wǎng)卡
這里以 Intel 網(wǎng)卡為例,有 10G、25G、100G 等,表示最大的傳輸速度,單位 Gbit/s。網(wǎng)卡可以有一個端口,也可以有多個端口。
網(wǎng)卡驅(qū)動知多少
假如我們從 Intel 買回來一張網(wǎng)卡,是不是直接插到電腦上,就可以用呢?答案是否定的。從一張物理網(wǎng)卡到真正能夠?qū)崿F(xiàn)收發(fā)報文,中間可是有一堆工作要做的。
- PCIe
PCIe 是一種高速串行點對點雙通道高帶寬、計算機擴展總線標(biāo)準,現(xiàn)在已經(jīng)發(fā)展到第四代了。簡單理解,就是計算機主板上用來插網(wǎng)卡的槽位。當(dāng)網(wǎng)卡插入主板上的槽位時,一塊網(wǎng)卡上的每個端口都對應(yīng)了一個 PCIe ID,這是網(wǎng)卡端口的物理身份標(biāo)識。這里提一句,PCI 是 PCIe 的上一個形態(tài)。
- 中斷
首先,你要明確一點:網(wǎng)卡收發(fā)報通過中斷實現(xiàn)。什么是中斷呢?
所謂中斷,就是外部設(shè)備向處理器發(fā)起的請求事件,但這還不夠本質(zhì)。更本質(zhì)的理解是處理器對外開放的實時受控接口。中斷絕對不是硬件代替軟件去輪詢,而是硬件的結(jié)構(gòu)決定了,當(dāng)某個管腳電平變低(或者變高)的時候,CPU 就會被打斷,并從特定地址開始執(zhí)行。比如,當(dāng) CPU 的 RESET 被拉低的時候一定會復(fù)位并從某個特定地址重新開始執(zhí)行,這是由硬件的結(jié)構(gòu)決定的。
- uio
uio,是一個內(nèi)核框架(操作系統(tǒng)提供的內(nèi)核模塊),作用就是支持用戶空間的 I/O 技術(shù)。而大家所熟知的 DPDK 開源組件就是實現(xiàn)用戶態(tài) I/O 技術(shù),它依賴內(nèi)核空間的 uio 框架。

- pmd
pmd(poll mode driver,輪詢模式驅(qū)動)是 DPDK 在用戶態(tài)實現(xiàn)的網(wǎng)卡驅(qū)動程序,準確來說,它應(yīng)該是個接口,它可以把 Intel 各種網(wǎng)卡的真正驅(qū)動程序加載到用戶態(tài)。
pmd 有哪些功能呢?比如對網(wǎng)卡硬件進行一些配置,例如設(shè)置網(wǎng)卡接收緩沖區(qū),發(fā)送緩沖區(qū)的大小。所謂對網(wǎng)卡進行配置, 也就是對網(wǎng)卡寄存器進行配置。每個網(wǎng)卡都有自己的配置空間,對應(yīng)了很多寄存器,每種寄存器各自負責(zé)不同的功能。比如接收控制寄存器,用于對網(wǎng)卡收發(fā)包的一些設(shè)置; 中斷寄存器,用于設(shè)置允許哪里產(chǎn)生中斷事件,例如鏈路中斷。
- igb_uio
igb_uio(也就是 DPDK 提供的 igb_uio.ko),是 DPDK 用于與 uio 交互的內(nèi)核模塊,通過 igb_uio 來 bind 指定的 PCI 網(wǎng)卡設(shè)備給到用戶態(tài)的 pmd 使用。igb_uio 借助 uio 技術(shù)來截獲中斷,并重設(shè)中斷回調(diào)行為,從而繞過內(nèi)核協(xié)議棧后續(xù)的處理流程。并且 igb_uio 會在內(nèi)核初始化的過程中將網(wǎng)卡硬件寄存器映射到用戶態(tài)。
- i40e、ixgbe 等
i40e 驅(qū)動對應(yīng) Intel x700 系列網(wǎng)卡,這是由 Intel 提供的,是網(wǎng)卡真正的驅(qū)動,需要加載 i40e.ko 到內(nèi)核,linux 操作系統(tǒng)才能識別這張物理網(wǎng)卡。而 ixgbe 是 Intel 82599 系列網(wǎng)卡驅(qū)動。
- 虛擬網(wǎng)卡
這個概念是伴隨著 vm(虛擬機)的產(chǎn)生而出現(xiàn)的,就是虛擬機上的網(wǎng)卡。我們可以將它和 host(物理機)上的物理網(wǎng)卡進行綁定。
總結(jié)
我們拿到 Intel 的一張網(wǎng)卡時,一般加載其對應(yīng)的網(wǎng)卡驅(qū)動就可以使用了,比如 i40e、ixgbe 等。但如果我們要用 DPDK 實現(xiàn)用戶態(tài)網(wǎng)卡收發(fā)包,就需要下載 Intel 等開源代碼 - DPDK,內(nèi)核需要加載 igb_uio,用戶態(tài) pmd 驅(qū)動框架需要加載 librte_i40e.so 等。
Linux 系統(tǒng)中 DPDK 編程常用命令
ifconfig
/sys/config/net-scripts/ 下的文件可以用來配置 eth 口的 ip 地址等
ip link show
lspci // 有很多可選參數(shù)
lsmod
su modprobe uio
su insmod igb_uio
dpdk主目錄/usrtools/ 下的 dpdk-devbind.py、dpdk-setup.sh 等自帶腳本
linux 用戶空間和內(nèi)核空間通信通過 sysfs 實現(xiàn)