目錄
2.3.2. 在 Linux 環境中使用 Hugepages
2.3.3. Linux 環境中 Xen Domain0 支持
3.3. Browsing the Installed DPDK Environment Target
5.6. Linux IOMMU Pass-Through使用Intel® VT-d運行DPDK
1. 簡介
本文檔包含DPDK軟件安裝和配置的相關說明。旨在幫助用戶快速啓動和運行軟件。文檔主要描述了在Linux環境下編譯和 運行DPDK應用程序,但是文檔並不深入DPDK的具體實現細節。
1.1. 文檔地圖
以下是一份建議順序閱讀的DPDK參考文檔列表:
-
發佈說明 : 提供特性發行版本的信息,包括支持的功能,限制,修復的問題,已知的問題等等。此外,還以FAQ方式提供了常見問題及解答。
-
**入門指南**(本文檔):介紹如何安裝和配置DPDK,旨在幫助用戶快速上手。
-
編程指南 :描述如下內容:
- 軟件架構及如何使用(實例介紹),特別是在Linux環境中的用法
- DPDK的主要內容,系統構建(包括可以在DPDK根目錄Makefile中來構建工具包和應用程序的命令)及應用移植細則。
- 軟件中使用的,以及新開發中需要考慮的一些優化。
還提供了文檔使用的術語表。
-
API參考 :提供有關DPDK功能、數據結構和其他編程結構的詳細信息。
-
示例程序用戶指南 :描述了一組例程。 每個章節描述了一個用例,展示了具體的功能,並提供了有關如何編譯、運行和使用的說明。
2. 系統要求
本章描述了編譯DPDK所需的軟件包。
假如在Intel公司的89xx通信芯片組平臺上使用DPDK,請參閱文檔 Intel® Communications Chipset 89xx Series Software for Linux Getting Started Guide。
2.1. X86 上預先設置 BIOS
對大多數平臺,使用基本DPDK功能無需對BIOS進行特殊設置。然而,對於HPET定時器和電源管理功能,以及爲了獲得40G網卡上小包處理的高性能,則可能需要更改BIOS設置。可以參閱章節 Enabling Additional Functionality 以獲取更爲詳細的信息。
2.2. 編譯DPDK
工具集:
以下說明在Fedora 18上通過了測試。其他系統所需要的安裝命令和軟件包可能有所不同。有關其他Linux發行版本和測試版本的詳細信息,請參閱DPDK發佈說明。
-
GNU
make
. -
coreutils:
cmp
,sed
,grep
,arch
等. -
gcc: 4.9以上的版本適用於所有的平臺。 在某些發佈版本中,啓用了一些特定的編譯器標誌和鏈接標誌(例如``-fstack-protector``)。請參閱文檔的發佈版本和
gcc -dumpspecs
. -
libc 頭文件,通常打包成
gcc-multilib
(glibc-devel.i686
/libc6-dev-i386
;glibc-devel.x86_64
/libc6-dev
用於Intel 64位架構編譯;glibc-devel.ppc64
用於IBM 64位架構編譯;) -
構建Linux內核模塊所需要的頭文件和源文件。(kernel - devel.x86_64; kernel - devel.ppc64)
-
在64位系統上編譯32位軟件包額外需要的軟件爲:
- glibc.i686, libgcc.i686, libstdc++.i686 及 glibc-devel.i686, 適用於Intel的i686/x86_64;
- glibc.ppc64, libgcc.ppc64, libstdc++.ppc64 及 glibc-devel.ppc64 適用於 IBM ppc_64;
Note
x86_x32 ABI目前僅在Ubuntu 13.10及以上版本或者Debian最近的發行版本上支持。編譯器必須是gcc 4.9+版本。
-
Python, 2.7+ or 3.2+版本, 用於運行DPDK軟件包中的各種幫助腳本。
可選工具:
- Intel® C++ Compiler (icc). 安裝icc可能需要額外的庫,請參閱編譯器安裝目錄下的icc安裝指南。
- IBM® Advance ToolChain for Powerlinux. 這是一組開源開發工具和運行庫。允許用戶在Linux上使用IBM最新POWER硬件的優勢。具體安裝請參閱IBM的官方安裝文檔。
- libpcap 頭文件和庫 (libpcap-devel) ,用於編譯和使用基於libcap的輪詢模式驅動程序。默認情況下,該驅動程序被禁用,可以通過在構建時修改配置文件
CONFIG_RTE_LIBRTE_PMD_PCAP=y
來開啓。 - 需要使用libarchive 頭文件和庫來進行某些使用tar獲取資源的單元測試。
2.3. 運行DPDK應用程序
要運行DPDK應用程序,需要在目標機器上進行某些定製。
2.3.1. 系統軟件
需求:
-
Kernel version >= 2.6.34
當前內核版本可以通過命令查看:
uname -r
glibc >= 2.7 (方便使用cpuset相關特性)
-
版本信息通命令
ldd --version
查看。 -
Kernel configuration
在 Fedora OS 及其他常見的發行版本中,如 Ubuntu 或 Red Hat Enterprise Linux,供應商提供的配置可以運行大多數的DPDK應用程序。
對於其他內核構件,應爲DPDK開啓的選項包括:
- UIO 支持
- HUGETLBFS 支持
- PROC_PAGE_MONITOR 支持
- 如果需要HPET支持,還應開啓 HPET and HPET_MMAP 配置選項。有關信息參考 High Precision Event Timer (HPET) Functionality 章節獲取更多信息。
2.3.2. 在 Linux 環境中使用 Hugepages
用於數據包緩衝區的大型內存池分配需要 Hugepages 支持(如上節所述,必須在運行的內核中開啓 HUGETLBFS 選項)。通過使用大頁分配,程序需要更少的頁面,性能增加, 因爲較少的TLB減少了將虛擬頁面地址翻譯成物理頁面地址所需的時間。如果沒有大頁,標準大小4k的頁面會導致頻繁的TLB miss,性能下降。
2.3.2.1. 預留 Hugepages 給 DPDK 使用
大頁分配應該在系統引導時或者啓動後儘快完成,以避免物理內存碎片化。要在引導時預留大頁,需要給Linux內核命令行傳遞一個參數。
對於2MB大小的頁面,只需要將hugepages選項傳遞給內核。如,預留1024個2MB大小的page,使用:
hugepages=1024
對於其他大小的hugepage,例如1G的頁,大小必須同時指定。例如,要預留4個1G大小的頁面給程序,需要傳遞以下選項給內核:
default_hugepagesz=1G hugepagesz=1G hugepages=4
CPU支持的hugepage大小可以從Intel架構上的CPU標誌位確定。如果存在pse,則支持2M個hugepages,如果page1gb存在,則支持1G的hugepages。
在IBM Power架構中,支持的hugepage大小爲16MB和16GB。
對於64位程序,如果平臺支持,建議使用1GB的hugepages。
在雙插槽NUMA的系統上,在啓動時預留的hugepage數目通常在兩個插槽之間評分(假設兩個插槽上都有足夠的內存)。
有關這些和其他內核選項的信息,請參閱Linux源代碼目錄中/kernel-parameter.txt文件。
特例:
對於2MB頁面,還可以在系統啓動之後再分配,通過向 /sys/devices/
目錄下的nr_hugepages文件寫入hugepage數目來實現。 對於單節點系統,使用的命令如下(假設需要1024個頁):
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
在NUMA設備中,分配應該明確指定在哪個節點上:
echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
對於1G頁面,系統啓動之後無法預留頁面內存。
2.3.2.2. DPDK 使用 Hugepages
一旦預留了hugepage內存,爲了使內存可用於DPDK,請執行以下步驟:
mkdir /mnt/huge mount -t hugetlbfs nodev /mnt/huge
通過將一下命令添加到 /etc/fstab
文件中,安裝點可以在重啓時永久保存:
nodev /mnt/huge hugetlbfs defaults 0 0
對於1GB內存,頁面大小必須在安裝選項中指定:
nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0
2.3.3. Linux 環境中 Xen Domain0 支持
現有的內存管理實現是基於Linux內核的hugepage機制。在Xen虛擬機管理程序中,對於DomainU客戶端的支持意味着DPDK程序與客戶一樣正常工作。
但是,Domain0不支持hugepages。爲了解決這個限制,添加了一個新的內核模塊rte_dom0_mm用於方便內存的分配和映射,通過 IOCTL (分配) 和 MMAP (映射).
2.3.3.1. DPDK 中使能 Xen Dom0模式
默認情況下,DPDK構建時禁止使用 Xen Dom0 模式。要支持 Xen Dom0,CONFIG_RTE_LIBRTE_XEN_DOM0設置應該改爲 “y”,編譯時棄用該模式。
此外,爲了允許接收錯誤套接字ID,CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID也必須設置爲 “y”。
2.3.3.2. 加載 DPDK rte_dom0_mm 模塊
要在Xen Dom0下運行任何DPDK應用程序,必須使用rsv_memsize選項將 rte_dom0_mm
模塊加載到運行的內核中。該模塊位於DPDK目標目錄的kmod子目錄中。應該使用insmod命令加載此模塊,如下所示:
sudo insmod kmod/rte_dom0_mm.ko rsv_memsize=X
X的值不能大於4096(MB).
2.3.3.3. 配置內存用於DPDK使用
在加載rte_dom0_mm.ko內核模塊之後,用戶必須配置DPDK使用的內存大小。這也是通過將內存大小寫入到目錄 /sys/devices/
下的文件memsize中來實現的。 使用以下命令(假設需要2048MB):
echo 2048 > /sys/kernel/mm/dom0-mm/memsize-mB/memsize
用戶還可以使用下面命令檢查已經使用了多少內存:
cat /sys/kernel/mm/dom0-mm/memsize-mB/memsize_rsvd
Xen Domain0 不支持NUMA配置,因此 --socket-mem
命令選項對Xen Domain0無效。
memsize的值不能大於rsv_memsize。
2.3.3.4. 在 Xen Domain0上運行DPDK程序
要在Xen Domain0上運行DPDK程序,需要一個額外的命令行選項 --xen-dom0
。
3. 使用源碼編譯DPDK目標文件
這個過程的部分工作可以通過章節 使用腳本快速構建 描述的腳本來實現。
3.1. 安裝DPDK及源碼
首先,解壓文件並進入到DPDK源文件根目錄下:
tar xJf dpdk-<version>.tar.xz cd dpdk-<version>
DPDK源文件由幾個目錄組成:
- lib: DPDK 庫文件
- drivers: DPDK 輪詢驅動源文件
- app: DPDK 應用程序 (自動測試)源文件
- examples: DPDK 應用例程
- config, buildtools, mk: 框架相關的makefile、腳本及配置文件
3.2. DPDK目標環境安裝
DPDK目標文件的格式爲:
ARCH-MACHINE-EXECENV-TOOLCHAIN
其中:
ARCH
可以是:i686
,x86_64
,ppc_64
MACHINE
可以是:native
,power8
EXECENV
可以是:linuxapp
,bsdapp
TOOLCHAIN
可以是:gcc
,icc
目標文件取決於運行環境是32位還是64位設備。可以在DPDK的 /config 目錄中找到可用的目標,不能使用defconfig_前綴。
配置文件根據 RTE_MACHINE
優化級別不同分別提供。在配置文件內部,RTE_MACHINE
配置爲 native,
意味着已編譯的軟件被調整到其構建的平臺上。有關此設置的更多信息,請參閱 DPDK 編程指南。
當使用Intel® C++ 編譯器 (icc)時,對64位和32位,需要使用以下命令進行調整。 注意,shell腳本會更新 $PATH
值,因此不能再同一個會話中執行。 此外,還應該檢查編譯器的安裝目錄,因爲可能不同。
source /opt/intel/bin/iccvars.sh intel64 source /opt/intel/bin/iccvars.sh ia32
在頂級目錄中使用 make install T=<target>
來生成目標文件。
例如,爲了使用icc編譯生成64位目標文件,運行如下命令:
make install T=x86_64-native-linuxapp-icc
爲了使用gcc編譯生成32位目標文件,命令如下:
make install T=i686-native-linuxapp-gcc
如果僅僅只是生成目標文件,並不運行,比如,配置文件改變需要重新編譯,使用 make config T=<target>
命令:
make config T=x86_64-native-linuxapp-gcc
Warning
任何需要運行的內核模塊,如 igb_uio
, kni
, 必須在與目標文件編譯相同的內核下進行編譯。 如果DPDK未在目標設備上構建,則應使用 RTE_KERNELDIR
環境變量將編譯指向要在目標機上使用的內核版本的副本(交叉編譯的內核版本)。
創建目標環境之後,用戶可以移動到目標環境目錄,並繼續更改代碼並編譯。用戶還可以通過編輯build目錄中的.config文件對DPDK配置進行修改。 (這是頂級目錄中defconfig文件的本地副本)。
cd x86_64-native-linuxapp-gcc vi .config make
此外,make clean命令可以用於刪除任何現有的編譯文件,以便後續完整、乾淨地重新編譯代碼。
3.3. Browsing the Installed DPDK Environment Target
一旦目標文件本創建,它就包含了構建客戶應用程序所需的DPDK環境的所有庫,包括輪詢驅動程序和頭文件。 此外,test和testpmd應用程序構建在build/app目錄下,可以用於測試。 還有一個kmod目錄,存放可能需要加載的內核模塊。
3.4. 加載模塊啓動DPDK環境需要的UIO功能
要運行任何的DPDK應用程序,需要將合適的uio模塊線加載到當前內核中。在多數情況下,Linux內核包含了標準的 uio_pci_generic
模塊就可以提供uio能力。 該模塊可以使用命令加載
sudo modprobe uio_pci_generic
區別於 uio_pci_generic
,DPDK提供了一個igb_uio模塊(可以在kmod目錄下找到)。可以通過如下方式加載:
sudo modprobe uio sudo insmod kmod/igb_uio.ko
Note
對於一下不支持傳統中斷的設備,例如虛擬功能(VF)設備,必須使用 igb_uio
來替代 uio_pci_generic
模塊。
由於DPDK 1.7版本提供VFIO支持,所以,對於支持VFIO的平臺,可選則UIO,也可以不用。
3.5. 加載VFIO模塊
DPDK程序選擇使用VFIO時,需要加載 vfio-pci
模塊:
sudo modprobe vfio-pci
注意,要使用VFIO,首先,你的平臺內核版本必須支持VFIO功能。 Linux內核從3.6.0版本之後就一直包含VFIO模塊,通常是默認存在的。不夠請查詢發行文檔以確認是否存在。
此外,要使用VFIO,內核和BIOS都必須支持,並配置爲使用IO虛擬化 (如 Intel® VT-d)。
爲了保證非特權用戶運行DPDK時能夠正確操作VFIO,還應設置正確的權限。這可以通過DPDK的配置腳本(dpdk-setup.sh文件位於usertools目錄中)。
3.6. 網絡端口綁定/解綁定到內核去頂模塊
從版本1.4開始,DPDK應用程序不再自動解除所有網絡端口與原先內核驅動模塊的綁定關係。 相反的,DPDK程序在運行前,需要將所要使用的端口綁定到 uio_pci_generic
, igb_uio
或 vfio-pci
模塊上。 任何Linux內核本身控制的端口無法被DPDK PMD驅動所使用。
Warning
默認情況下,DPDK將在啓動時不再自動解綁定內核模塊與端口的關係。DPDK應用程序使用的任何端口必須與Linux無關,並綁定到 uio_pci_generic
, igb_uio
或 vfio-pci
模塊上。
將端口從Linux內核解綁,然後綁定到 uio_pci_generic
, igb_uio
或 vfio-pci
模塊上供DPDK使用,可以使用腳本dpdk_nic _bind.py(位於usertools目錄下)。 這個工具可以用於提供當前系統上網絡接口的狀態圖,綁定或解綁定來自不同內核模塊的接口。 以下是腳本如何使用的一些實例。通過使用 --help
or --usage
選項調用腳本,可以獲得腳本的完整描述與幫助信息。 請注意,要將接口綁定到uio或vfio的話,需要先將這兩個模塊加載到內核,再運行 dpdk-devbind.py
腳本。
Warning
由於VFIO的工作方式,設備是否可用VFIO是有明確限制的。大部分是由IOMMU組的功能決定的。
任何的虛擬設備可以獨立使用VFIO,但是物理設備則要求將所有端口綁定到VFIO,或者其中一些綁定到VFIO,而其他端口不能綁定到任何其他驅動程序。
如果你的設備位於PCI-to-PCI橋之後,橋接器將成爲設備所在的IOMMU組的一部分。因此,橋接驅動程序也應該從端口解綁定。
Warning
雖然任何用戶都可以運行dpdk-devbind.py腳本來查看網絡接口的狀態,但是綁定和解綁定則需要root權限。
查看系統中所有網絡接口的狀態:
./usertools/dpdk-devbind.py --status Network devices using DPDK-compatible driver ============================================ 0000:82:00.0 '82599EB 10-GbE NIC' drv=uio_pci_generic unused=ixgbe 0000:82:00.1 '82599EB 10-GbE NIC' drv=uio_pci_generic unused=ixgbe Network devices using kernel driver =================================== 0000:04:00.0 'I350 1-GbE NIC' if=em0 drv=igb unused=uio_pci_generic *Active* 0000:04:00.1 'I350 1-GbE NIC' if=eth1 drv=igb unused=uio_pci_generic 0000:04:00.2 'I350 1-GbE NIC' if=eth2 drv=igb unused=uio_pci_generic 0000:04:00.3 'I350 1-GbE NIC' if=eth3 drv=igb unused=uio_pci_generic Other network devices ===================== <none>
綁定設備 eth1
,``04:00.1``, 到 uio_pci_generic
驅動:
./usertools/dpdk-devbind.py --bind=uio_pci_generic 04:00.1
或者
./usertools/dpdk-devbind.py --bind=uio_pci_generic eth1
恢復設備 82:00.0
到Linux內核綁定狀態:
./usertools/dpdk-devbind.py --bind=ixgbe 82:00.0
4. 編譯和運行簡單應用程序
本章介紹如何在DPDK環境下編譯和運行應用程序。還指出應用程序的存儲位置。
Note
此過程的部分操作也可以使用腳本來完成。參考 使用腳本快速構建 章節描述。
4.1. 編譯一個簡單應用程序
一個DPDK目標環境創建完成時(如 x86_64-native-linuxapp-gcc
),它包含編譯一個應用程序所需要的全部庫和頭文件。
當在Linux* 交叉環境中編譯應用程序時,以下變量需要預先導出:
RTE_SDK
- 指向DPDK安裝目錄。RTE_TARGET
- 指向DPDK目標環境目錄。
以下是創建 helloworld
應用程序實例,該實例將在DPDK Linux環境中運行。 這個實例可以在目錄 ${RTE_SDK}/examples
找到。
該目錄包含 main.c
文件。該文件與DPDK目標環境中的庫結合使用時,調用各種函數初始化DPDK環境, 然後,爲每個要使用的core啓動一個入口點(調度應用程序)。 默認情況下,二進制文件存儲在build目錄中。
cd examples/helloworld/ export RTE_SDK=$HOME/DPDK export RTE_TARGET=x86_64-native-linuxapp-gcc make CC main.o LD helloworld INSTALL-APP helloworld INSTALL-MAP helloworld.map ls build/app helloworld helloworld.map
Note
在上面的例子中, helloworld
是在DPDK的目錄結構下的。 當然,也可以將其放在DPDK目錄之外,以保證DPDK的結構不變。 下面的例子, helloworld
應用程序被複制到一個新的目錄下。
export RTE_SDK=/home/user/DPDK cp -r $(RTE_SDK)/examples/helloworld my_rte_app cd my_rte_app/ export RTE_TARGET=x86_64-native-linuxapp-gcc make CC main.o LD helloworld INSTALL-APP helloworld INSTALL-MAP helloworld.map
4.2. 運行一個簡單的應用程序
Warning
UIO驅動和hugepage必須在程序運行前設置好。
Warning
應用程序使用的任何端口,必須綁定到合適的內核驅動模塊上,如章節 網絡端口綁定/解綁定到內核去頂模塊 描述的那樣。
應用程序與DPDK目標環境的環境抽象層(EAL)庫相關聯,該庫提供了所有DPDK程序通用的一些選項。
以下是EAL提供的一些選項列表:
./rte-app -c COREMASK [-n NUM] [-b <domain:bus:devid.func>] \ [--socket-mem=MB,...] [-m MB] [-r NUM] [-v] [--file-prefix] \ [--proc-type <primary|secondary|auto>] [-- xen-dom0]
選項描述如下:
-c COREMASK
: 要運行的內核的十六進制掩碼。注意,平臺之間編號可能不同,需要事先確定。-n NUM
: 每個處理器插槽的內存通道數目。-b <domain:bus:devid.func>
: 端口黑名單,避免EAL使用指定的PCI設備。--use-device
: 僅使用指定的以太網設備。使用逗號分隔[domain:]bus:devid.func
值,不能與-b
選項一起使用。--socket-mem
: 從特定插槽上的hugepage分配內存。-m MB
: 內存從hugepage分配,不管處理器插槽。建議使用--socket-mem
而非這個選項。-r NUM
: 內存數量。-v
: 顯示啓動時的版本信息。--huge-dir
: 掛載hugetlbfs的目錄。--file-prefix
: 用於hugepage文件名的前綴文本。--proc-type
: 程序實例的類型。--xen-dom0
: 支持在Xen Domain0上運行,但不具有hugetlbfs的程序。--vmware-tsc-map
: 使用VMware TSC 映射而不是本地RDTSC。--base-virtaddr
: 指定基本虛擬地址。--vfio-intr
: 指定要由VFIO使用的中斷類型。(如果不支持VFIO,則配置無效)。
其中 -c
是強制性的,其他爲可選配置。
將DPDK應用程序二進制文件拷貝到目標設備,按照如下命令運行(我們假設每個平臺處理器有4個內存通道,並且存在core0~3用於運行程序):
./helloworld -c f -n 4
Note
選項 --proc-type
和 --file-prefix
用於運行多個DPDK進程。請參閱 “多應用程序實例” 章節及 DPDK 編程指南 獲取更多細節。
4.2.1. 應用程序使用的邏輯Core
對於DPDK應用程序,coremask參數始終是必須的。掩碼的每個位對應於Linux提供的邏輯core ID。 由於這些邏輯core的編號,以及他們在NUMA插槽上的映射可能因平臺而異,因此建議在選擇每種情況下使用的coremaks時,都要考慮每個平臺的core佈局。
在DPDK程序初始化EAL層時,將顯示要使用的邏輯core及其插槽位置。可以通過讀取 /proc/cpuinfo
文件來獲取系統上所有core的信息。例如執行 cat /proc/cpuinfo
。 列出來的physical id 屬性表示其所屬的CPU插槽。當使用了其他處理器來了解邏輯core到插槽的映射時,這些信息很有用。
Note
可以使用另一個Linux工具 lstopo
來獲取邏輯core佈局的圖形化信息。在Fedora Linux上, 可以通過如下命令安裝並運行工具:
sudo yum install hwloc ./lstopo
Warning
邏輯core在不同的電路板上可能不同,在應用程序使用coremaks時需要先確定。
4.2.2. 應用程序使用的Hugepage內存
當運行應用程序時,建議使用的內存與hugepage預留的內存一致。如果運行時沒有 -m
或 --socket-mem
參數傳入,這由DPDK應用程序在啓動時自動完成。
如果通過顯示傳入 -m
或 --socket-mem
值,但是請求的內存超過了該值,應用程序將執行失敗。 但是,如果用戶請求的內存小於預留的hugepage-memory,應用程序也會失敗,特別是當使用了 -m
選項的時候。 因爲,假設系統在插槽0和插槽1上有1024個預留的2MB頁面,如果用戶請求128 MB的內存,可能存在64個頁不符合要求的情況:
- 內核只能在插槽1中將hugepage-memory提供給應用程序。在這種情況下,如果應用程序嘗試創建一個插槽0中的對象,例如ring或者內存池,那麼將執行失敗 爲了避免這個問題,建議使用
--socket-mem
選項替代-m
選項。 - 這些頁面可能位於物理內存中的任意位置,儘管DPDK EAL將嘗試在連續的內存塊中分配內存,但是頁面可能是不連續的。在這種情況下,應用程序無法分配大內存。
使用socket-mem選項可以爲特定的插槽請求特定大小的內存。通過提供 --socket-mem
標誌和每個插槽需要的內存數量來實現的,如 --socket-mem=0,512
用於在插槽1上預留512MB內存。 類似的,在4插槽系統上,如果只能在插槽0和2上分配1GB內存,則可以使用參數``–socket-mem=1024,0,1024`` 來實現。 如果DPDK無法在每個插槽上分配足夠的內存,則EAL初始化失敗。
4.3. 其他示例程序
其他的一些示例程序包含在${RTE_SDK}/examples 目錄下。這些示例程序可以使用本手冊前面部分所述的方法進行構建運行。另外,請參閱 DPDK示例程序用戶指南 瞭解應用程序的描述、編譯和執行的具體說明以及代碼解釋。
4.4. 附加的測試程序
此外,還有兩個在創建庫時構建的應用程序。這些源文件位於 DPDK/app目錄下,稱爲test和testpmd程序。創建庫之後,可以在build目錄中找到。
- test程序爲DPDK中的各種功能提供具體的測試。
- testpmd程序提供了許多不同的數據包吞吐測試,例如,在Intel® 82599 10 Gigabit Ethernet Controller中如何使用Flow Director。
5. 啓用附加功能
5.1. 高精度事件定時器 (HPET) 功能
5.1.1. BIOS 支持
要使用HPET功能時,必須先在平臺BIOS上開啓高精度定時器。否則,默認情況下使用時間戳計數器 (TSC) 。 通常情況下,起機時按 F2 可以訪問BIOS。然後用戶可以導航到HPET選項。 在Crystal Forest平臺BIOS上,路徑爲:Advanced -> PCH-IO Configuration -> High Precision Timer -> (如果需要,將Disabled 改爲 Enabled )。
在已經起機的系統上,可以使用以下命令來檢查HPET是否啓用
grep hpet /proc/timer_list
如果沒有條目,則必須在BIOS中啓用HPET,鑌鐵重新啓動系統。
5.1.2. Linux 內核支持
DPDK通過將定時器計數器映射到進程地址空間來使用平臺的HPET功能,因此,要求開啓 HPET_MMAP
系統內核配置選項。
Warning
在Fedora或者其他常見的Linux發行版本(如Ubuntu)中,默認不會啓用 HPET_MMAP
選項。 要重新編譯啓動此選項的內核,請參閱發行版本的相關說明。
5.1.3. DPDK 中使能 HPET
默認情況下,DPDK配置文件中是禁用HPET功能的。要使用HPET,需要將 CONFIG_RTE_LIBEAL_USE_HPET
設置爲 y
來開啓編譯。
對於那些使用 rte_get_hpet_cycles()
及 rte_get_hpet_hz()
API接口的應用程序, 並且選擇了HPET作爲rte_timer庫的默認時鐘源,需要在初始化時調用 rte_eal_hpet_init()
API。 這個API調用將保證HPET可用,如果HPET不可用(例如,內核沒有開啓 HPET_MMAP
使能),則向程序返回一個錯誤值。 如果HPET在運行時不可用,應用程序可以方便的採取其他措施。
Note
對於那些僅需要普通定時器API,而不是HPET定時器的應用程序,建議使用 rte_get_timer_cycles()
和 rte_get_timer_hz()
API調用,而不是HPET API。 這些通用的API兼容TSC和HPET時鐘源,具體時鐘源則取決於應用程序是否調用 ``rte_eal_hpet_init()``初始化,以及運行時系統上可用的時鐘。
5.2. 沒有Root權限情況下運行DPDK應用程序
雖然DPDK應用程序直接使用了網絡端口及其他硬件資源,但通過許多小的權限調整,可以允許除root權限之外的用戶運行這些應用程序。 爲了保證普通的Linux用戶也可以運行這些程序,需要調整如下Linux文件系統權限:
-
所有用於hugepage掛載點的文件和目錄,如
/mnt/huge
-
/dev
中的UIO設備文件,如/dev/uio0
,/dev/uio1
等 -
UIO系統配置和源文件,如
uio0
:/sys/class/uio/uio0/device/config /sys/class/uio/uio0/device/resource*
-
如果要使用HPET,那麼
/dev/hpet
目錄也要修改
Note
在某些Linux 安裝中, /dev/hugepages
也是默認創建hugepage掛載點的文件。
5.3. 電源管理和節能功能
如果要使用DPDK的電源管理功能,必須在平臺BIOS中啓用增強的Intel SpeedStep® Technology。否則,sys文件夾下 /sys/devices/system/cpu/cpu0/cpufreq
將不存在,不能使用基於CPU頻率的電源管理。請參閱相關的BIOS文檔以確定如何訪問這些設置。
例如,在某些Intel參考平臺上,開啓Enhanced Intel SpeedStep® Technology 的路徑爲:
Advanced -> Processor Configuration -> Enhanced Intel SpeedStep® Tech
此外,C3 和 C6 也應該使能以支持電源管理。C3 和 C6 的配置路徑爲:
Advanced -> Processor Configuration -> Processor C3 Advanced -> Processor Configuration -> Processor C6
5.4. 使用 Linux Core 隔離來減少上下文切換
雖然DPDK應用程序使用的線程固定在系統的邏輯核上,但Linux調度程序也可以在這些核上運行其他任務。 爲了防止在這些核上運行額外的工作負載,可以使用 isolcpus
Linux 內核參數來將其與通用的Linux調度程序隔離開來。
例如,如果DPDK應用程序要在邏輯核2,4,6上運行,應將以下內容添加到內核參數表中:
isolcpus=2,4,6
5.5. 加載 DPDK KNI 內核模塊
要運行DPDK Kernel NIC Interface (KNI) 應用程序,需要將一個額外的內核模塊(kni模塊)加載到內核中。 該模塊位於DPDK目錄kmod子目錄中。與 igb_uio
模塊加載類似,(假設當前目錄就是DPDK目錄):
insmod kmod/rte_kni.ko
Note
相關的詳細信息,可以參閱 “Kernel NIC Interface Sample Application” 章節和 DPDK 示例程序用戶指南 。
5.6. Linux IOMMU Pass-Through使用Intel® VT-d運行DPDK
要在Linux內核中啓用Intel® VT-d,必須配置一系列內核選項,包括:
IOMMU_SUPPORT
IOMMU_API
INTEL_IOMMU
另外,要使用Intel® VT-d運行DPDK,使用 igb_uio
驅動時必須攜帶 iommu=pt
參數。 這使得主機可以直接通過DMA重映射查找。 另外,如果內核中沒有設置 INTEL_IOMMU_DEFAULT_ON
參數,那麼也必須使用 intel_iommu=on
參數。這可以確保 Intel IOMMU 被正確初始化。
請注意,對於``igb_uio`` 驅動程序,使用 iommu = pt
是必須de ,vfio-pci
驅動程序實際上可以同時使用 iommu = pt
和 iommu = on
。
5.7. 40G NIC上的小包處理高性能
由於在最新版本中可能提供用於性能提升的固件修復,因此最好進行固件更新以獲取更高的性能。 請和 Intel’s Network Division 工程師聯繫以進行固件更新。 用戶可以參考DPDK版本發行說明,以使用 i40e 驅動程序識別NIC的已驗證固件版本。
5.7.1. 使用16B大小的RX描述符
由於 i40e PMD 支持16B和32B的RX描述符,而16B大小的描述符可以幫助小型數據包提供性能,因此,配置文件中 CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC
更改爲使用16B大小的描述符。
5.7.2. 高性能和每數據包延遲權衡
由於硬件設計,每個數據包描述符回寫都需要NIC內部的中斷信號。中斷的最小間隔可以在編譯時通過配置文件中的 CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL
指定。 雖然有默認配置,但是該配置可以由用戶自行調整,這取決於用戶所關心的內容,整體性能或者每數據包延遲。
6. 使用腳本快速構建
usertools目錄中的dpdk-setup.sh腳本,向用戶提供了快速執行如下任務功能:
- 構建DPDK庫
- 加載/卸載DPDK IGB_UIO內核模塊
- 加載/卸載VFIO內核模塊
- 加載/卸載DPDK KNI內核模塊
- 創建/刪除NUMA 或 non-NUMA平臺的hugepages
- 查看網絡端口狀態和預留給DPDK應用程序使用的端口
- 設置非root用戶使用VFIO的權限
- 運行test和testpmd應用程序
- 查看meminfo中的hugepages
- 列出在
/mnt/huge
中的hugepages - 刪除內置的DPDK庫
對於其中一個EAL目標,一旦完成了這些步驟,用戶就可以編譯自己的在EAL庫中鏈接的應用程序來創建DPDK映像。
6.1. 腳本組織
dpdk-setup.sh腳本在邏輯上組織成用戶按順序執行的一系列步驟。每個步驟都提供了許多選項來指導用戶完成所需的任務。以下是每個步驟的簡單介紹:
Step 1: Build DPDK Libraries
最開始,用戶必須指定tagert的類型以便編譯正確的庫。
如本入門指南前面的章節描述,用戶必須在此之前就安裝好所有的庫、模塊、更新和編譯器。
Step 2: Setup Environment
用戶需要配置Linux* 環境以支持DPDK應用程序的運行。 可以爲NUMA 或non-NUMA系統分配Hugepages。任何原來已經存在的hugepages將被刪除。 也可以在此步驟中插入所需的DPDK內核模塊,並且可以將網絡端口綁定到此模塊供DPDK使用。
Step 3: Run an Application
一旦執行了其他步驟,用戶就可以運行test程序。該程序允許用戶爲DPDK運行一系列功能測試。也可以運行支持數據包接收和發送的testpmd程序。
Step 4: Examining the System
此步驟提供了一些用於檢查Hugepage映射狀態的工具。
Step 5: System Cleanup
最後一步具有將系統恢復到原始狀態的選項。
6.2. Use Cases
以下是使用dpdk-setup.sh的示例。腳本應該使用source命令運行。腳本中的某些選項在繼續操作之前提示用戶需要進一步的數據輸入。
Warning
必須與root全選運行dpdk-setup.sh。
source usertools/dpdk-setup.sh ------------------------------------------------------------------------ RTE_SDK exported as /home/user/rte ------------------------------------------------------------------------ Step 1: Select the DPDK environment to build ------------------------------------------------------------------------ [1] i686-native-linuxapp-gcc [2] i686-native-linuxapp-icc [3] ppc_64-power8-linuxapp-gcc [4] x86_64-native-bsdapp-clang [5] x86_64-native-bsdapp-gcc [6] x86_64-native-linuxapp-clang [7] x86_64-native-linuxapp-gcc [8] x86_64-native-linuxapp-icc ------------------------------------------------------------------------ Step 2: Setup linuxapp environment ------------------------------------------------------------------------ [11] Insert IGB UIO module [12] Insert VFIO module [13] Insert KNI module [14] Setup hugepage mappings for non-NUMA systems [15] Setup hugepage mappings for NUMA systems [16] Display current Ethernet device settings [17] Bind Ethernet device to IGB UIO module [18] Bind Ethernet device to VFIO module [19] Setup VFIO permissions ------------------------------------------------------------------------ Step 3: Run test application for linuxapp environment ------------------------------------------------------------------------ [20] Run test application ($RTE_TARGET/app/test) [21] Run testpmd application in interactive mode ($RTE_TARGET/app/testpmd) ------------------------------------------------------------------------ Step 4: Other tools ------------------------------------------------------------------------ [22] List hugepage info from /proc/meminfo ------------------------------------------------------------------------ Step 5: Uninstall and system cleanup ------------------------------------------------------------------------ [23] Uninstall all targets [24] Unbind NICs from IGB UIO driver [25] Remove IGB UIO module [26] Remove VFIO module [27] Remove KNI module [28] Remove hugepage mappings [29] Exit Script
Option:
以下選項演示了 “x86_64-native-linuxapp-gcc“ DPDK庫的創建。
Option: 9 ================== Installing x86_64-native-linuxapp-gcc Configuration done == Build lib ... Build complete RTE_TARGET exported as x86_64-native-linuxapp-gcc
以下選項用於啓動DPDK UIO驅動程序。
Option: 25 Unloading any existing DPDK UIO module Loading DPDK UIO module
以下選項演示了在NUMA系統中創建hugepage。爲每個node分配1024個2MB的頁。 應用程序應該使用 -m 4096 來啓動,以便訪問這兩個內存區域。(如果沒有 -m 選項,則自動完成)。
Note
如果顯示提示以刪除臨時文件,請輸入’y’。
Option: 15 Removing currently reserved hugepages mounting /mnt/huge and removing directory Input the number of 2MB pages for each node Example: to have 128MB of hugepages available per node, enter '64' to reserve 64 * 2MB pages on each node Number of pages for node0: 1024 Number of pages for node1: 1024 Reserving hugepages Creating /mnt/huge and mounting as hugetlbfs
以下操作說明了啓動測試應用程序以在單個core上運行
Option: 20 Enter hex bitmask of cores to execute test app on Example: to execute app on cores 0 to 7, enter 0xff bitmask: 0x01 Launching app EAL: coremask set to 1 EAL: Detected lcore 0 on socket 0 ... EAL: Master core 0 is ready (tid=1b2ad720) RTE>>
6.3. 應用程序
一旦用戶運行和dpdk-setup.sh腳本,構建了目標程序並且設置了hugepages,用戶就可以繼續構建和運行自己的應用程序或者源碼中提供的示例。
/examples 目錄中提供的示例程序爲了解DPDK提供了很好的起點。 以下命令顯示了helloworld應用程序的構建和運行方式。 按照4.2.1節,”應用程序使用的邏輯Core”描述,當選擇用於應用程序的coremask時,需要確定平臺的邏輯core的佈局。
cd helloworld/ make CC main.o LD helloworld INSTALL-APP helloworld INSTALL-MAP helloworld.map sudo ./build/app/helloworld -c 0xf -n 3 [sudo] password for rte: EAL: coremask set to f EAL: Detected lcore 0 as core 0 on socket 0 EAL: Detected lcore 1 as core 0 on socket 1 EAL: Detected lcore 2 as core 1 on socket 0 EAL: Detected lcore 3 as core 1 on socket 1 EAL: Setting up hugepage memory... EAL: Ask a virtual area of 0x200000 bytes EAL: Virtual area found at 0x7f0add800000 (size = 0x200000) EAL: Ask a virtual area of 0x3d400000 bytes EAL: Virtual area found at 0x7f0aa0200000 (size = 0x3d400000) EAL: Ask a virtual area of 0x400000 bytes EAL: Virtual area found at 0x7f0a9fc00000 (size = 0x400000) EAL: Ask a virtual area of 0x400000 bytes EAL: Virtual area found at 0x7f0a9f600000 (size = 0x400000) EAL: Ask a virtual area of 0x400000 bytes EAL: Virtual area found at 0x7f0a9f000000 (size = 0x400000) EAL: Ask a virtual area of 0x800000 bytes EAL: Virtual area found at 0x7f0a9e600000 (size = 0x800000) EAL: Ask a virtual area of 0x800000 bytes EAL: Virtual area found at 0x7f0a9dc00000 (size = 0x800000) EAL: Ask a virtual area of 0x400000 bytes EAL: Virtual area found at 0x7f0a9d600000 (size = 0x400000) EAL: Ask a virtual area of 0x400000 bytes EAL: Virtual area found at 0x7f0a9d000000 (size = 0x400000) EAL: Ask a virtual area of 0x400000 bytes EAL: Virtual area found at 0x7f0a9ca00000 (size = 0x400000) EAL: Ask a virtual area of 0x200000 bytes EAL: Virtual area found at 0x7f0a9c600000 (size = 0x200000) EAL: Ask a virtual area of 0x200000 bytes EAL: Virtual area found at 0x7f0a9c200000 (size = 0x200000) EAL: Ask a virtual area of 0x3fc00000 bytes EAL: Virtual area found at 0x7f0a5c400000 (size = 0x3fc00000) EAL: Ask a virtual area of 0x200000 bytes EAL: Virtual area found at 0x7f0a5c000000 (size = 0x200000) EAL: Requesting 1024 pages of size 2MB from socket 0 EAL: Requesting 1024 pages of size 2MB from socket 1 EAL: Master core 0 is ready (tid=de25b700) EAL: Core 1 is ready (tid=5b7fe700) EAL: Core 3 is ready (tid=5a7fc700) EAL: Core 2 is ready (tid=5affd700) hello from core 1 hello from core 2 hello from core 3 hello from core 0
7. 如何獲取Intel平臺上網卡的最佳性能
本文檔一步一步教你如何在Intel平臺上運行DPDK程序以獲取最佳性能。
7.1. 硬件及存儲需求
爲了獲得最佳性能,請使用Intel Xeon級服務器系統,如Ivy Bridge,Haswell或更高版本。
確保每個內存通道至少插入一個內存DIMM,每個內存通道的內存大小至少爲4GB。 Note: 這對性能有最直接的影響。
可以通過使用 dmidecode
來檢查內存配置:
dmidecode -t memory | grep Locator Locator: DIMM_A1 Bank Locator: NODE 1 Locator: DIMM_A2 Bank Locator: NODE 1 Locator: DIMM_B1 Bank Locator: NODE 1 Locator: DIMM_B2 Bank Locator: NODE 1 ... Locator: DIMM_G1 Bank Locator: NODE 2 Locator: DIMM_G2 Bank Locator: NODE 2 Locator: DIMM_H1 Bank Locator: NODE 2 Locator: DIMM_H2 Bank Locator: NODE 2
上面的示例輸出顯示共有8個通道,從 A
到 H
,每個通道都有2個DIMM。
你也可以使用 dmidecode
來確定內存頻率:
dmidecode -t memory | grep Speed Speed: 2133 MHz Configured Clock Speed: 2134 MHz Speed: Unknown Configured Clock Speed: Unknown Speed: 2133 MHz Configured Clock Speed: 2134 MHz Speed: Unknown ... Speed: 2133 MHz Configured Clock Speed: 2134 MHz Speed: Unknown Configured Clock Speed: Unknown Speed: 2133 MHz Configured Clock Speed: 2134 MHz Speed: Unknown Configured Clock Speed: Unknown
輸出顯示2133 MHz(DDR4)和未知(不存在)的速度。這與先前的輸出一致,表明每個通道都有一個存儲。
7.1.1. 網卡需求
使用 DPDK supported <http://dpdk.org/doc/nics> 描述的高端NIC,如Intel XL710 40GbE。
確保每個網卡已經更新最新版本的NVM/固件。
使用PCIe Gen3 插槽,如 Gen3 x8
或者 Gen3 x16
,因爲PCIe Gen2 插槽不能提供2 x 10GbE或更高的帶寬。 可以使用 lspci
命令來檢查PCI插槽的速率:
lspci -s 03:00.1 -vv | grep LnkSta LnkSta: Speed 8GT/s, Width x8, TrErr- Train- SlotClk+ DLActive- ... LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ ...
當將NIC插入PCI插槽時,需要查看屏幕輸出,如 CPU0 或 CPU1,以指示連接的插槽。
同時應該注意NUMA,如果使用不同網卡的2個或更多端口,最好確保這些NIC在同一個CPU插槽上,下面進一步展示瞭如何確定這一點。
7.1.2. BIOS 設置
以下是關於BIOS設置的一些建議。不同的平臺可能會有不同的名字,因此如下僅用於參考:
- 開始之前,請考慮將所有BIOS設置爲默認值
- 禁用所有省電選項,如電源性能調整、CPU P-State, CPU C3 Report and CPU C6 Report。
- 選擇 Performance 作爲CPU電源及性能策略。
- 禁用Turbo Boost以確保性能縮放隨着內核數量的增加而增加。
- 將內存頻率設置爲最高可用的值,NOT auto。
- 當測試NIC的物理功能時,禁用所有的虛擬化選項,如果要使用VFIO,請打開
VT-d
if you wants to use VFIO.
7.1.3. Linux引導選項
以下是GRUB啓動選項的一些建議配置:
-
使用默認的grub文件作爲起點
-
通過grub配置保留1G的hugepage。例如,保留8個1G大小的頁面:
default_hugepagesz=1G hugepagesz=1G hugepages=8
-
隔離將用於DPDK的CPU core.如:
isolcpus=2,3,4,5,6,7,8
-
如果要使用VFIO,請使用以下附加的grub參數:
iommu=pt intel_iommu=on
7.2. 運行DPDK前的配置
-
構建目標文件,預留hugepage。參閱前面 在 Linux 環境中使用 Hugepages 描述。
以下命令爲具體過程:
# Build DPDK target. cd dpdk_folder make install T=x86_64-native-linuxapp-gcc -j # Get the hugepage size. awk '/Hugepagesize/ {print $2}' /proc/meminfo # Get the total huge page numbers. awk '/HugePages_Total/ {print $2} ' /proc/meminfo # Unmount the hugepages. umount `awk '/hugetlbfs/ {print $2}' /proc/mounts` # Create the hugepage mount folder. mkdir -p /mnt/huge # Mount to the specific folder. mount -t hugetlbfs nodev /mnt/huge
-
使用命令
cpu_layout
來檢查CPU佈局:cd dpdk_folder usertools/cpu_layout.py
或者運行
lscpu
檢查每個插槽上的core。 -
檢查NIC ID和插槽ID:
# 列出所有的網卡的PCI地址及設備ID. lspci -nn | grep Eth
例如,假設你的輸入如下:
82:00.0 Ethernet [0200]: Intel XL710 for 40GbE QSFP+ [8086:1583] 82:00.1 Ethernet [0200]: Intel XL710 for 40GbE QSFP+ [8086:1583] 85:00.0 Ethernet [0200]: Intel XL710 for 40GbE QSFP+ [8086:1583] 85:00.1 Ethernet [0200]: Intel XL710 for 40GbE QSFP+ [8086:1583]
檢測PCI設備相關聯的NUMA節點:
cat /sys/bus/pci/devices/0000\:xx\:00.x/numa_node
通常的,
0x:00.x
表示在插槽0,而8x:00.x
表示在插槽1。 Note: 爲了說去最佳性能,請保證core和NIC位於同一插槽中。 在上面的例子中85:00.0
在插槽1,因此必須被插槽1上的core使用才能獲得最佳性能。 -
將測試端口綁定到DPDK兼容的驅動程序,如igb_uio。例如,將兩個端口綁定到兼容DPDK的驅動程序並檢查狀態:
# 綁定端口 82:00.0 和 85:00.0 到DPDK驅動 ./dpdk_folder/usertools/dpdk-devbind.py -b igb_uio 82:00.0 85:00.0 # 檢查端口驅動狀態 ./dpdk_folder/usertools/dpdk-devbind.py --status
運行
dpdk-devbind.py --help
以獲取更多信息。
有關DPDK設置和Linux內核需求的更多信息,請參閱 使用源碼編譯DPDK目標文件 。
7.3. 網卡最佳性能實踐舉例
以下是運行DPDK l3fwd
例程並獲取最佳性能的例子。使用 Intel 服務平臺和Intel XL710 NICs。 具體的40G NIC配置請參閱i40e NIC指南。
本例場景是通過兩個Intel XL710 40GbE端口獲取最優性能。請參閱 Fig. 7.1 用於性能測試設置。
Fig. 7.1 性能測試搭建
-
將兩個Intel XL710 NIC添加到平臺,並使用每個卡一個端口來獲得最佳性能。使用兩個NIC的原因是克服PCIe Gen3的限制,因爲它不能提供80G帶寬。 對於兩個40G端口,但兩個不同的PCIe Gen3 x8插槽可以。 請參考上面的示例NIC輸出,然後我們可以選擇
82:00.0
及85:00.0
作爲測試端口:82:00.0 Ethernet [0200]: Intel XL710 for 40GbE QSFP+ [8086:1583] 85:00.0 Ethernet [0200]: Intel XL710 for 40GbE QSFP+ [8086:1583]
-
將端口連接到打流機,對於高速測試,最好有專用的打流設備。
-
檢測PCI設備的numa節點,並獲取該插槽id上的core。 在本例中,
82:00.0
和85:00.0
都在插槽1上,插槽1上的core id爲18-35 和 54-71。 Note: 不要在同一個core上使用兩個邏輯核(e.g core18 有兩個邏輯核core18 and core54),而是使用來自不同core的兩個邏輯核。 -
將這兩個端口綁定到igb_uio。
-
對於XL710 40G 端口,我們需要至少兩個隊列來實現最佳性能,因此每個端口需要兩個隊列,每個隊列將需要專用的CPU內核來接收/發送數據包。
-
使用DPDK示例程序
l3fwd
做性能測試,兩個端口進行雙向轉發,使用默認的lpm模式編譯l3fwd sample
。 -
運行l3fwd的命令如下所示:
./l3fwd -c 0x3c0000 -n 4 -w 82:00.0 -w 85:00.0 \ -- -p 0x3 --config '(0,0,18),(0,1,19),(1,0,20),(1,1,21)'
命令表示應用程序使用(core18,port0,隊列0),(core19,port0,隊列1), (core20,port1,隊列0),(core18,port1,隊列1)。
-
配置打流機用於發包
- 創建流
- 設置報文類型爲Ethernet II type to 0x0800。