DPDK快速上手(linux)
本文檔主要來自linux_gsg-18.02.pdf的翻譯,翻譯肯定有不妥之處,請批評指正,我會随後修改,不勝感激。
1. 介紹
本文檔包含有關DPDK(Data Plane Development Kit的縮寫)軟體的安裝和配置的說明,目的就是讓使用者快速用起來。本文檔描述怎樣在linux應用環境下編譯和運作一個DPDK應用程式,而不過多深入細節。
1.1文檔路線圖
以下是針對所有DPDK文檔建議的閱讀順序:
-
釋出說明(Release Notes):
提供具體的釋出資訊,包括支援特性、限制、問題改進、問題報告等等。也提供以FAQ形式的常見問題的回答。
-
快速上手指南(Getting Started Guide),即本文檔:
描述在不同的作業系統上如何安裝和配置DPDK軟體;幫助使用者快速用起來。
-
程式設計者指南(programmer's guide):
描述:
- 軟體架構和怎麼用它(通過例子),特别是在linux應用環境下。
- DPDK的内容,系統建構(包括用在DPDK根目錄 Makefile中的指令,用來建構開發工具包和應用程式)以及移植應用程式的準則。
- 軟體中使用的優化以及新開發應考慮的優化。
-
API參考(API Reference):
提供有關DPDK函數、資料結構和其它程式設計結構的詳細資訊。
-
示例應用程式使用者指南(sample applications user guides):
介紹一組示例應用程式。 每章描述了一個示例應用程式,該應用程式展示了特定的功能并提供了關于如何編譯、運作和使用示例應用程式的說明。
2. 系統要求
本章介紹編譯DPDK所需的軟體包。
注意:
如果DPDK用在Intel®通信晶片組89xx系列的平台,請參閱“Intel®通信晶片組89xx系列軟體Linux版上手指南”。
2.1 x86上BIOS設定的先決條件
對于大多數平台,不需要特殊的BIOS設定即可使用基本的DPDK功能。 但是,對于額外的HPET定時器(譯者注:High Precision Event Timer高精度定時器)和電源管理功能以及小包的高性能,可能需要更改BIOS設定。 有關所需更改的更多資訊,請參閱“啟用附加功能”部分。
注意:
如果啟用UEFI(譯者注:Unified Extensible Firmware Interface 統一的可擴充固件接口)安全引導,則Linux核心可能會禁止在系統上使用UIO。 是以,由DPDK使用的裝置應綁定到vfio-pci核心子產品,而不是igb_uio或uio_pci_generic。 有關更多詳細資訊,請參閱“從核心子產品綁定和解除綁定網絡端口”部分。
2.2 編譯DPDK所需
所需的工具和庫:
各種系統所需的安裝指令和安裝軟體包可能會有所不同。 有關Linux發行版和測試版本的詳細資訊,請參閱DPDK釋出說明(Release Notes)。
-
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 Power架構上的64位編譯)
- 建構核心子產品所需的Linux核心頭檔案或源代碼(kernel-devel.x86_64; kernel-devel.ppc64)
- 在64位系統上進行32位編譯所需的其它軟體包:
- 針對Intel i686/x86_64的glibc.i686、libgcc.i686、libstdc++.i686和glibc-devel.i686;
- 針對IBM ppc_64的glibc.ppc64、libgcc.ppc64、libstdc++.ppc64和glibc-devel.ppc64;
x86_x32 ABI目前僅支援在高于13.10的Ubuntu或最近的Debian發行版的發行包。 唯一支援的編譯器是gcc 4.9+。
-
libnuma-devel
用于處理NUMA(非一緻記憶體通路)的庫。
-
Python 2.7+或3.2+版本
可以使用DPDK包中包含的各種幫助程式腳本。
可選的工具:
-
Intel®C++編譯器(icc)。
對于其安裝,可能需要額外的庫。 請參閱icc編譯器安裝文檔目錄中的安裝指南。
-
IBM®進階工具鍊,針對Powerlinux。
這是一套開源開發工具和實時運作庫,它允許使用者在Linux上獲得IBM最新POWER硬體功能的領先優勢。 要安裝它,請參閱IBM官方安裝文檔。
-
libpcap頭檔案和庫(libpcap-devel)
用于編譯并使用基于libpcap的輪詢模式驅動程式。 該驅動程式預設是禁用的,可以通過在編譯時配置檔案中設定 CONFIG_RTE_LIBRTE_PMD_PCAP=y 來啟用。
-
libarchive頭檔案和庫
是使用tar擷取資源的一些單元測試所必需的。
2.3 運作DPDK應用程式所需
要運作DPDK應用程式,目标機器上可能需要做一些定制化。
2.3.1 系統軟體
所需:
-
核心版本>= 3.2
所需的核心版本基于當開發DPDK版本時在kernel.org上提供的最老的長期穩定核心。正在使用的核心版本可以使用以下指令進行檢查:uname -r
-
glibc> = 2.7(用于與cpuset相關的特性)
該版本可以使用ldd --version指令進行檢查。
-
核心配置
在Fedora OS和其它常見發行版(如Ubuntu或Red Hat Enterprise Linux)中,供應商提供的核心配置可用于運作大多數DPDK應用程式。
對于其它核心版本,應該為DPDK啟用的選項包括:
- hugetlbfs
- PROC_PAGE_MONITOR支援
- 如果需要HPET支援,則還應啟用HPET和HPET_MMAP配置選項。有關更多詳細資訊,請參閱“高精度事件定時器(HPET)功能”部分。
2.3.2 在Linux環境中使用巨頁(Hugepages)
用于資料包緩沖區的大記憶體池配置設定需要Hugepage支援(必須在正在運作的核心中啟用HUGETLBFS選項,如前一部分所示)。 通過使用Hugepage配置設定,需要更少的頁面而使性能得以提高,是以減少了TLB(即轉換檢測緩沖區,高速轉換緩存),這減少了将虛拟頁面位址轉換為實體頁面位址所需的時間。 沒有Hugepage,TLB發生高缺失率伴随着标準4k頁面大小,進而導緻性能下降。
2.3.2.1 為DPDK的使用預留Hugepages
應該在引導時或在系統引導後盡快完成Hugepages的配置設定,以防止記憶體在實體記憶體中被碎片化。 要在引導時預留Hugepages,一個參數将在核心指令行上傳遞給Linux核心。
對于2 MB頁面,隻需将hugepages選項傳遞給核心即可。 例如,要預留2 MB的1024頁,使用:
hugepages=1024
其它hugepage尺寸,例如1G頁面大小必須明确指定,也可以可選擇的設定為系統的預設hugepage大小。例如,在四個1G頁面的形式預留4G的hugepage記憶體,下面的選項應該傳遞給核心:
default_hugepagesz=1G hugepagesz=1G hugepages=4
CPU支援的hugepage大小可以通過Intel架構上的CPU标志确定。 如果存在pse,則支援2M的hugepages; 如果存在pdpe1gb,則支援1G的hugepages。 在IBM Power架構上,支援的hugepage大小為16MB和16GB。
對于64位應用程式,如果平台支援它,則建議使用1GB的hugepages。
對于雙socket NUMA系統,在引導時預留的hugepages的數目通常在兩個socket之間平均配置設定(假設兩個socket上都有足夠的記憶體)。
有關這些和其它核心選項的更多詳細資訊,請參閱Linux源代碼樹中的Documentation/kernel-parameters.txt檔案。
#####替代方案:
對于2MB頁面,系統啟動後還可以選擇配置設定hugepages。 這是通過echo /sys/devices/目錄中的nr_hugepages檔案所需的hugepages數目來完成的。 對于單節點系統,使用的指令如下(假定需要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頁面,系統啟動後無法預留hugepage記憶體。
在IBM POWER系統上,應将nr_overcommit_hugepages設定為與nr_hugepages相同的值。 例如,如果所需的頁數是128,則使用以下指令:
echo 128 > /sys/kernel/mm/hugepages/hugepages-16384kB/nr_hugepages
echo 128 > /sys/kernel/mm/hugepages/hugepages-16384kB/nr_overcommit_hugepages
2.3.3 在DPDK中使用Hugepages
一旦預留了hugepage記憶體,為了使記憶體可用于DPDK,請執行以下步驟:
mkdir /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
通過将以下行添加到/etc/fstab檔案,可以在重新啟動後使挂載點永久儲存:
nodev /mnt/huge hugetlbfs defaults 0 0
對于1GB頁面,頁面大小必須指定為挂載(mount)選項:
nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0
3. 從源碼編譯DPDK目标(target)
此過程的一部分也可以使用本文檔的“快速上手安裝腳本”部分中介紹的安裝腳本來完成。
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、arm64
- MACHINE可以是:native、power8、armv8a
- EXECENV可以是:linuxapp、bsdapp
- TOOLCHAIN可以是: gcc、icc
要安裝的目标取決于安裝在主機上的32位和/或64位軟體包和編譯器。 可用的目标可以在DPDK/config目錄中找到。 不應該使用defconfig_字首。
配置檔案随RTE_MACHINE優化級别集(optimization level set)一起提供。 在配置檔案中,RTE_MACHINE配置值被設定為native,這意味着已編譯的軟體已針對其所建構的平台進行了調整。 有關此設定的更多資訊及其可能值,請參閱“DPDK程式員指南(Programmers Guide)”。
使用Intel®C++編譯器(icc)時,應分别調用以下指令之一,以分别使用64位或32位。 請注意,shell腳本更新$PATH變量,是以不應在同一個會話中執行。 另外,請核實編譯器的安裝目錄,因為路徑可能會不同:
source /opt/intel/bin/iccvars.sh intel64
source /opt/intel/bin/iccvars.sh ia32
要安裝和制作目标,請在頂級DPDK目錄中使用 make install T=<target> 指令。
例如,要使用icc編譯64位目标,請運作:
make install T=x86_64-native-linuxapp-icc
要使用gcc編譯32位版本,make指令應該是:
make install T=i686-native-linuxapp-gcc
如果要在目标建構之前預處理它,請使用 make config T=<target> 指令, 例如在編譯之前需要進行配置更改:
make config T=x86_64-native-linuxapp-gcc
警告:
任何要使用的核心子產品,例如 igb_uio,kni,必須使用與目标上運作的相同的核心下進行編譯。 如果DPDK未在目标機器上建構,則應使用RTE_KERNELDIR環境變量将編譯指向要在目标機器上使用的核心版本的拷貝。
一旦目标環境被建立,使用者可以切到目标環境目錄并繼續進行代碼更改和重新編譯。 使用者也可以通過編輯建構(build)目錄中的.config檔案來修改編譯時DPDK配置。 (這是來自頂層config目錄的defconfig檔案的一個用來建構本地的拷貝)。
cd x86_64-native-linuxapp-gcc
vi .config
make
另外,make clean指令可以用于删除任何已存在的編譯檔案,以便後續的全面幹淨重新建構代碼。
3.3 浏覽已安裝的DPDK環境目标
建立目标後,它将包含所有庫,包括用于建構客戶應用程式所需的DPDK環境的輪詢模式驅動程式和頭檔案。 另外,test和testpmd應用程式是在 build/app 目錄下建構的,可用于測試。 kmod目錄也存在,其中包含可能需要加載的核心子產品。
4. Linux驅動程式
為了正常工作,不同的PMD(譯者注:實體媒體關聯層接口)可能需要不同的核心驅動程式。 取決于正在使用的PMD,相應的核心驅動程式應該加載并綁定到網絡端口。
4.1 UIO
一個用于設定裝置的小的核心子產品,将裝置記憶體映射到使用者空間并注冊中斷。 在許多情況下,Linux核心中包含的标準uio_pci_generic子產品可以提供uio功能。 該子產品可以使用以下指令加載:
sudo modprobe uio_pci_generic
uio_pci_generic子產品不支援虛拟功能(virtual functions)的建立。
作為uio_pci_generic的替代方案,DPDK還包含igb_uio子產品,該子產品可以在上面提到的kmod子目錄中找到。 它可以如下所示加載:
sudo modprobe uio
sudo insmod kmod/igb_uio.ko
對于一些不支援傳統中斷的裝置,例如 虛拟功能(VF)裝置,可能需要使用igb_uio子產品來代替uio_pci_generic。
如果啟用UEFI安全引導,則Linux核心可能會禁止在系統上使用UIO。 是以,由DPDK使用的裝置應綁定到vfio-pci核心子產品,而不是igb_uio或uio_pci_generic。 有關更多詳細資訊,請參閱下面的“與核心子產品綁定和解除綁定網絡端口”。
DPDK 1.7以上版本提供了VFIO支援,是以對于支援使用VFIO的平台,使用UIO是可選的。
4.2 VFIO
依靠IOMMU保護,與UIO相比,它是更強大、更安全的驅動程式。 要使用VFIO,必須加載vfio-pci子產品:
sudo modprobe vfio-pci
請注意,為了使用VFIO,您的核心必須支援它。 VFIO核心子產品自Linux核心3.6.0版以來已包含在核心中,通常是預設存在的,但請查閱您的發行版文檔以確定是這樣的。
此外,要使用VFIO,核心和BIOS必須支援并配置為使用IO虛拟化(如Intel®VT-d)。
vfio-pci子產品不支援虛拟功能(virtual functions)的建立。
為了在作為非特權使用者運作DPDK應用程式時正确操作VFIO,還應該設定正确的權限。 這個可以通過使用DPDK設定腳本(調用位于usertools目錄下的腳本dpdk-setup.sh)來完成。
VFIO可以在沒有IOMMU的情況下使用。 雖然這與使用UIO一樣不安全,但它确實使使用者能夠在IOMMU不可用的情況下保持VFIO具有的裝置通路和程式設計的程度。
4.3 分叉驅動程式(Bifurcated Driver )
使用分叉驅動程式的PMD與裝置核心驅動程式共存。 在這種模式下,NIC由核心控制,而資料路徑則由PMD直接在裝置上執行。
這種模式具有以下優點:
- 記憶體管理和隔離是由核心完成的,是以它是安全和強大的。
- 它使使用者能夠在相同的網絡端口上運作DPDK應用程式時使用傳統的Linux工具,例如ethtool或ifconfig。
-
它使DPDK應用程式隻能過濾部分流量,而其餘部分将由核心驅動程式定向和處理。
關于分叉驅動程式的更多資訊可以在“Mellanox Bifurcated DPDK PMD”中找到。
4.4 與核心子產品綁定和解除綁定網絡端口
使用分叉驅動程式的PMD不應從其核心驅動程式中解除綁定。 本部分适用于使用UIO或VFIO驅動程式的PMD。
從版本1.4開始,DPDK應用程式不再自動解除所有支援的網絡端口與正在使用的核心驅動程式的綁定。 相反,如果正在使用的PMD使用UIO或VFIO驅動程式,那麼DPDK應用程式要使用的所有端口都必須在應用程式運作之前綁定到uio_pci_generic、igb_uio或vfio-pci子產品。 對于此類PMD,Linux* 控制下的任何網絡端口都将被忽略,并且不能被應用程式使用。
要将端口綁定到uio_pci_generic、igb_uio或vfio-pci子產品以使用DPDK,然後将端口傳回到Linux* 控制,則在usertools子目錄中提供了名為dpdk-devbind.py的應用程式腳本。 此應用可用于提供系統上網絡端口目前狀态的視圖,以及從不同核心子產品(包括uio和vfio子產品)綁定和取消綁定這些端口。 以下是腳本如何使用的一些示例。 腳本及其參數的完整描述可以通過使用--help或--usage選項調用腳本來獲得。 請注意,在運作dpdk-devbind.py腳本之前,應将要使用的uio或vfio核心子產品加載到核心中。
警告:
由于VFIO的工作方式,VFIO可以使用哪些裝置有一定的限制。 主要歸結為IOMMU組的工作方式。 任何虛拟功能裝置都可以與VFIO一起使用,但實體裝置也将需要綁定到VFIO的所有端口,或者其中一些虛拟功能裝置綁定到VFIO,而其他虛拟功能裝置則不需要任何綁定。
如果您的裝置位于PCI-to-PCI橋之後,則該橋将成為您的裝置所在的IOMMU組的一部分。是以,橋驅動程式也應該從橋PCI裝置解除綁定,以便VFIO與在橋後面的裝置一起工作。
雖然任何使用者都可以運作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恢複到其原來的核心綁定:
./usertools/dpdk-devbind.py --bind=ixgbe 82:00.0
5. 編譯和運作示例應用程式
本章介紹如何在DPDK環境中編譯和運作應用程式。 它還提供了一個指向示例應用程式存儲位置的指針。
注意:
此過程的一部分也可以使用本文檔中“快速上手安裝腳本”部分所述的安裝腳本來完成。
5.1 編譯一個示例應用程式
一旦建立了DPDK目标環境目錄(例如x86_64-native-linuxapp-gcc),它将包含建構應用程式所需的所有庫和頭檔案。
在DPDK上編譯Linux* 環境中的應用程式時,必須導出(原文:export)以下變量:
- RTE_SDK - 指向DPDK安裝目錄。
- RTE_TARGET - 指向DPDK目标環境目錄。
以下是建立在DPDK Linux環境中運作的helloworld應用程式的示例。 這個例子可以在${RTE_SDK}/examples目錄中找到。 該目錄包含main.c檔案。 該檔案與DPDK目标環境中的庫結合使用時,會調用各種函數來初始化DPDK環境,然後為要使用的每個核(原文:core)啟動入口點(排程應用程式)。 預設情況下,該二進制檔案在建構目錄中生成。
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
在上面的例子中,helloworld位于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
5.2 運作一個示例應用程式
在運作應用程式之前,請確定:
- Hugepages設定完成。
- 用到的任何核心驅動程式已加載。
- 在需要的情況下,應用程式使用的端口應該綁定到相應的核心驅動程式。
請參閱“Linux驅動程式”部分了解詳情。
該應用程式與DPDK目标環境的環境抽象層(EAL)庫連結,該庫提供了一些通用于每個DPDK應用程式的選項。
以下是可以提供給EAL的選項清單:
./rte-app [-c COREMASK | -l CORELIST] [-n NUM] [-b <domain:bus:devid.func>] \
[--socket-mem=MB,...] [-d LIB.so|DIR] [-m MB] [-r NUM] [-v] [--file-prefix] \
[--proc-type <primary|secondary|auto>]
EAL選項如下:
- -c COREMASK或-l CORELIST:要運作的核的十六進制位掩碼(譯者注:COREMASK)。請注意,核編号可能會在平台之間發生變化,應事先确定。核清單(譯者注:CORELIST)是一組核數字而不是位圖核掩碼。
- -n NUM:每個處理器socket的記憶體通道數量。
- -b <domain:bus:devid.func>:端口的黑名單;阻止EAL使用指定的PCI裝置(允許使用多個-b選項)。
- --use-device:僅使用指定的以太網裝置。使用逗号分隔[domain:] bus:devid.func值。不能與-b選項一起使用。
- --socket-mem:記憶體從socket上的hugepages配置設定。
- -d:添加要加載的驅動程式或驅動程式目錄。 應用程式應該使用此選項來加載建構為共享庫的pmd驅動程式。
- -m MB:無論處理器socket如何,都可以從hugepages配置設定記憶體。 建議使用--socket-mem來代替這個選項。
- -r NUM:記憶體排名(原文:rank)的數量。
- -v:啟動時顯示的版本資訊。
- --huge-dir:挂載(原文:mount)hugetlbfs的目錄。
- mbuf-pool-ops-name:池操作使用的mbuf名稱。
- --file-prefix:用于hugepages檔案名的字首文本。
- --proc-type:程序執行個體(原文:process instance)的類型
- --vmware-tsc-map:使用VMware TSC地圖(???原文:map)而不是本地RDTSC。
- --base-virtaddr:指定虛拟位址基位址(???原文:base virtual address)。
- --vfio-intr:指定VFIO要使用的中斷類型(如果不使用VFIO,則不起作用)。
-c或-l和選項是必需的; 其它都是可選的。
将DPDK應用程式二進制檔案複制到您的目标(原文:target),然後按如下方式運作應用程式(假設平台每個處理器socket有四個記憶體通道,并且核0-3存在并将用于運作應用程式):
./helloworld -l 0-3 -n 4
----------------------------------
**注意:**
--proc-type和--file-prefix EAL選項用于運作多個DPDK程序。 有關更多詳細資訊,請參閱“DPDK示例應用程式使用者指南”的“多程序示例應用程式”一章和“DPDK程式員指南”。
----------------------------------
#### 5.2.1 應用程式的邏輯核使用(原文:Logical Core Use by Applications)
對于DPDK應用程式,核掩碼(-c 0x0f)或核清單(-l 0-3)參數始終是必需的。掩碼的每一位對應于Linux報告的等效邏輯核編号。首選用corelist選項,它是定義要使用的核的更清晰的方法。由于這些邏輯核心編号及其映射到的在特定NUMA套接字上特定的核可能因平台而異,是以建議在選擇每種情況下使用的核掩碼/核清單時,應考慮每個平台的核布局。
在DPDK應用程式初始化EAL層時,将顯示要使用的邏輯核及其socket位置。也可以通過檢查/proc/cpuinfo檔案(例如,通過運作cat /proc/cpuinfo)為系統上的所有核确定此資訊。為每個處理器列出的實體ID屬性訓示它所屬的CPU socket。當使用其它處理器來了解邏輯核到socket的映射時,這會很有用。
----------------------------------
**注意:**
使用Linux應用程式lstopo可以獲得邏輯核布局的更多圖形視圖。 在Fedora Linux上,可以使用以下指令安裝并運作:
sudo yum install hwloc
./lstopo
----------------------------------
**警告:**
邏輯核布局可以在不同的闆布局之間切換,并且應在選擇應用程式核掩碼/核清單之前進行檢查。
----------------------------------
#### 5.2.2 應用程式的巨頁(原文:Hugepage)記憶體使用
運作應用程式時,建議使用與配置設定給巨頁相同數量的記憶體。 這是DPDK應用程式在啟動時自動完成的,如果在運作時沒有-m或--socket-mem參數傳遞給它。
如果通過顯式傳遞-m或--socket-mem值來請求更多記憶體,則應用程式将失敗。 但是,如果使用者請求的記憶體少于巨大頁記憶體的預留量,那麼應用程式本身也可能失敗,特别是在使用-m選項時。 原因如下。 假設系統在socket0中有1024個預留的2MB頁面和在socket1中有1024個。如果使用者請求128MB記憶體,則64個頁面可能與限制(原文:constraint)不比對:
- 僅由socket1中的核心給予應用程式的巨頁記憶體。 在這種情況下,如果應用程式嘗試建立一個對象(例如socket0中的環形或記憶體池),則會失敗。 為避免此問題,建議使用--socket-mem選項代替-m選項。
- 這些頁面可以位于實體記憶體中的任何位置,盡管DPDK EAL會嘗試在連續的塊中配置設定記憶體,但頁面可能不會連續。 在這種情況下,應用程式無法配置設定大記憶體池。
socket-mem選項可用于為特定socket請求特定數量的記憶體。 這是通過提供--socket-mem标志後跟在每個socket上請求的記憶體量來實作的,例如,supply --socket-mem=0,512試圖為socket1預留512MB。 同樣,在一個四socket系統上,為了在socket0和2上每個配置設定1GB的記憶體,可以使用參數--socket-mem=1024,0,1024。 在沒有明确涉及的任何CPUsocket上不會預留記憶體,例如在這種情況下的socket3。 如果DPDK無法在每個socket上配置設定足夠的記憶體,則EAL初始化失敗。
### 5.3 其它示例應用程式
其它示例應用程式包含在${RTE_SDK}/examples目錄中。這些示例應用程式可以按照本手冊前面部分所述的方式建構和運作。另外,請參閱“DPDK示例應用程式使用者指南”以擷取應用程式的描述,編譯和執行的特定說明以及代碼的一些解釋。
### 5.4 其它的測試應用程式
另外,還有兩個其它應用程式是在建立庫時建構的。這些源檔案位于DPDK/app目錄中,稱為test和testpmd。一旦建立了這些庫,就可以在build/app目錄中找到它們。
測試應用程式為DPDK中的各種功能提供了各種特定的測試。
應用程式testpmd提供了許多不同的資料包吞吐量測試和功能示例,例如如何使用Intel®82599萬兆以太網控制器中的Flow Director。
--------------------------------------------------
--------------------------------------------------
## 6. 啟用附加功能
### 6.1 高精度事件定時器(HPET)功能
#### 6.1.1 BIOS支援
如果要使用HPET,則必須在平台BIOS中啟用高精度定時器(HPET)。 否則,預設使用時間戳計數器(TSC)。 通常在平台啟動時按F2鍵來通路BIOS。 使用者然後可以導航到HPET選項。 在Crystal Forest平台的BIOS中,路徑為:Advanced -> PCH-IO Configuration -> High Precision Timer ->(如果需要,從禁用更改為啟用)。
在已經啟動完的系統上,可以發出以下指令來檢查HPET是否已啟用:
grep hpet / proc / timer_list
如果沒有條目傳回,則必須在BIOS中啟用HPET(按照上述說明)并重新開機系統。
#### 6.1.2 Linux核心支援
DPDK通過将定時器計數器映射到程序位址空間來利用平台HPET定時器,是以要求啟用HPET_MMAP核心配置選項。
----------------------------------
**警告:**
在Fedora以及其他常見發行版(如Ubuntu)中,預設情況下未啟用HPET_MMAP核心選項。 要在啟用此選項的情況下重新編譯Linux核心,請從釋出文檔查閱相關說明。
----------------------------------
#### 6.1.3 在DPDK中啟用HPET
預設情況下,DPDK的建構配置檔案中禁用HPET。要使用HPET,應将CONFIG_RTE_LIBEAL_USE_HPET設定更改為y,這将在編譯時啟用HPET設定。
對于應用程式使用rte_get_hpet_cycles()和rte_get_hpet_hz()的API調用,并且可選地将HPET設定為rte_timer庫的預設時間源,應在應用程式初始化時調用新的rte_eal_hpet_init()API調用。此API調用将确定HPET是可通路的,如果不是,則會向應用程式傳回錯誤,例如,如果HPET_MMAP未在核心中啟用。然後,應用程式可以确定在運作時HPET不可用時要采取的操作(如果有的話)。
----------------------------------
**注意:**
對于需要計時API的應用程式,特别是不需要HPET計時器,建議使用rte_get_timer_cycles()和rte_get_timer_hz()API調用代替HPET特定的API。這些通用API可以與TSC或HPET時間源一起使用,具體取決于應用程式對rte_eal_hpet_init()的請求(如果有)以及系統在運作時可用的東西。
----------------------------------
### 6.2 運作沒有Root權限的DPDK應用程式
----------------------------------
**注意:**
下面的說明将允許在較早的Linux核心版本中非root使用者運作DPDK。但是,從版本4.0開始,核心不允許非特權程序從頁面映射檔案中讀取實體位址資訊,進而使這些程序無法使用需要實體位址的硬體(原文:HW)裝置。
----------------------------------
雖然使用DPDK的應用程式直接使用網絡端口和其他硬體資源,但通過一些小的權限調整,可以以“root”以外的使用者身份運作這些應用程式。為此,應調整以下Linux檔案系統對象的所有權或權限,以確定用于運作DPDK應用程式的Linux使用者帳戶可以通路它們:
- 所有用作巨頁挂載點的目錄,例如/mnt/huge
- /dev中的userspace-io(譯者注:UIO)裝置檔案,例如/dev/uio0,/dev/uio1等
- userspace-io sysfs配置和資源檔案,例如uio0:
/sys/class/uio/uio0/device/config
/sys/class/uio/uio0/device/resource*
- 如果要使用HPET,/dev/hpet
----------------------------------
**注意:**
在某些Linux安裝中,/dev/hugepages也是預設建立的一個巨頁挂載點。
----------------------------------
### 6.3 電源管理和省電功能
如果要使用DPDK的電源管理功能,必須在平台BIOS中啟用增強型Intel SpeedStep®技術(Enhanced Intel SpeedStep® Technology)。 否則,sys檔案檔案夾/sys/devices/system/cpu/cpu0/cpufreq将不存在,并且不能使用基于CPU頻率的電源管理。 請參閱相關BIOS文檔以确定如何通路這些設定。
例如,在某些Intel參考平台BIOS變體上,增強型Intel SpeedStep®技術的路徑是:
Advanced
-> Processor Configuration
-> Enhanced Intel SpeedStep® Tech
另外,還應該啟用C3和C6以進行電源管理。 C3和C6在同一個平台BIOS上的路徑是:
-> Processor C3 Advanced
-> Processor C6
### 6.4 使用Linux核隔離(原文:Linux Core Isolation)來減少上下文切換
雖然DPDK應用程式使用的線程固定在系統上的邏輯核中,但Linux排程程式也可以在這些核上運作其它任務。 為了防止在這些核上運作額外的工作負載,可以使用Linux核心參數isolcpus将它們與正常Linux排程程式隔離。
例如,如果要在邏輯核2,4和6上運作DPDK應用程式,則應将以下内容添加到核心參數清單中:
isolcpus=2,4,6
### 6.5 加載DPDK KNI核心子產品
要運作DPDK 核心NIC接口(KNI)的示例應用程式,必須将一個額外的核心子產品(kni子產品)加載到正在運作的核心中。 該子產品位于DPDK目标目錄的kmod子目錄中。 與加載igb_uio子產品類似,應該使用insmod指令加載該子產品,如下所示(假定目前目錄是DPDK目标目錄):
insmod kmod/rte_kni.ko
----------------------------------
**注意:**
有關更多詳細資訊,請參閱“DPDK示例應用程式使用者指南”中的“核心NIC接口示例應用程式”一章。
----------------------------------
### 6.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。 這會導緻主機中的DMAR(DMA重新映射)查找的透傳。 另外,如果INTEL_IOMMU_DEFAULT_ON未在核心中設定,則必須使用核心參數intel_iommu=on。 這可確定Intel IOMMU按預期進行初始化。
請注意,雖然使用iommu=pt對于igb_uio驅動程式是強制性的,但vfio-pci驅動程式實際上可以使用iommu=pt和iommu=on兩者一起工作。
--------------------------------------------------
--------------------------------------------------
## 7. 快速上手安裝腳本
在usertools子目錄中找到的dpdk-setup.sh腳本,允許使用者執行以下任務:
- 建構DPDK庫
- 插入和移除DPDK IGB_UIO核心子產品
- 插入和删除VFIO核心子產品
- 插入和移除DPDK KNI核心子產品
- 為NUMA和非NUMA的場景建立和删除巨頁
- 檢視網絡端口狀态和為DPDK應用程式使用預留端口
- 設定使用VFIO作為非特權使用者的權限
- 運作測試和testpmd應用程式
- 看看meminfo中的巨頁
- 在/mnt/huge列出巨頁
- 删除已建構的DPDK庫
一旦EAL目标之一完成了這些步驟,使用者就可以編譯自己的應用程式,連結到EAL庫中以建立DPDK鏡像(原文:image)。
### 7.1 腳本的組織結構
dpdk-setup.sh腳本在邏輯上組織成使用者按順序執行的一系列步驟。每個步驟都提供了許多指導使用者完成所需任務的選項。以下是每個步驟的簡要說明。
#### 第1步:建構DPDK庫
最初,使用者必須選擇一個DPDK目标,以便在建構庫時選擇正确的目标類型和編譯器選項。
正如本上手指南前面的章節所述,使用者必須先在系統中安裝所有庫、子產品、更新和編譯器。
#### 第2步:安裝環境
使用者配置Linux* 環境以支援DPDK應用程式的運作。可以為NUMA或非NUMA系統設定巨頁。 任何現有的巨頁将被删除。所需的DPDK核心子產品也可以在此步驟中插入,網絡端口可以綁定到此子產品以供DPDK應用程式使用。
#### 第3步:運作應用程式
一旦執行了其它步驟,使用者可以運作測試應用程式。 測試應用程式允許使用者為DPDK運作一系列功能測試。 testpmd應用程式支援資料包的接收和發送,也可以運作。
#### 第4步:檢查系統
這一步提供了一些工具來檢查巨頁映射的狀态。
#### 第5步:系統清理
最後一步有将系統恢複到原始狀态的選項。
### 7.2 用例
以下是如何使用dpdk-setup.sh腳本的一些示例。 該腳本應該使用source指令運作。 繼續之前,腳本中的某些選項會提示使用者輸入更多資料。
----------------------------------
**警告:**
dpdk-setup.sh腳本應該以root權限運作。
----------------------------------
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系統中建立巨頁的過程。 1024個2 MByte頁面配置設定給每個節點。 結果是應用程式應該使用-m 4096來啟動應用程式來通路兩個存儲區(如果未提供-m選項,這将自動完成)。
----------------------------------
**注意:**
如果顯示提示以删除臨時檔案,請鍵入'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
以下選擇示範了測試應用程式在單核上運作的啟動。
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>>
### 7.3 應用程式
一旦使用者運作了dpdk-setup.sh腳本,建構了一個EAL目标并設定了巨頁(如果使用其中一個Linux EAL目标),使用者就可以繼續建構并運作他們的應用程式或其中一個提供的例子。
/examples目錄中的示例為了解DPDK的操作提供了一個很好的起點。 以下指令序列顯示了helloworld示例應用程式怎樣建構和運作。 正如第4.2.1節“應用程式的邏輯核使用”中所建議的那樣,應在選擇用于應用程式的核掩碼時确定平台的邏輯核布局。
cd helloworld/
CC main.o
LD helloworld
INSTALL-APP helloworld
INSTALL-MAP helloworld.map
sudo ./build/app/helloworld -l 0-3 -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: Virtual area found at 0x7f0a9f600000 (size = 0x400000)
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: Virtual area found at 0x7f0a9dc00000 (size = 0x800000)
EAL: Virtual area found at 0x7f0a9d600000 (size = 0x400000)
EAL: Virtual area found at 0x7f0a9d000000 (size = 0x400000)
EAL: Virtual area found at 0x7f0a9ca00000 (size = 0x400000)
EAL: Virtual area found at 0x7f0a9c600000 (size = 0x200000)
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: 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
--------------------------------------------------
--------------------------------------------------
## 8. 如何使Intel平台上的NIC獲得最佳性能
本部分文檔是在Intel平台上DPDK應用程式獲得高性能的分步指南。
### 8.1 硬體和記憶體要求
為了獲得最佳性能,請使用Intel Xeon類伺服器系統,如Ivy Bridge,Haswell或更新的。
確定每個記憶體通道至少插入一個記憶體DIMM(譯者注:Dual-Inline-Memory-Modules 雙列直插式存儲子產品),并且每個記憶體的記憶體大小至少為4GB。 注意:這對性能有最直接的影響。
您可以使用dmidecode檢查記憶體配置,如下所示:
dmidecode -t memory | grep Locator
Locator: DIMM_A1
Bank Locator: NODE 1
Locator: DIMM_A2
Locator: DIMM_B1
Locator: DIMM_B2
Locator: DIMM_G1
Bank Locator: NODE 2
Locator: DIMM_G2
Locator: DIMM_H1
Locator: DIMM_H2
上面的示例輸出顯示總共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
輸出顯示速度為2133 MHz(DDR4)和未知(不存在)。 這與之前的輸出一緻,表明每個通道都有一個記憶體條。
#### 8.1.1 網絡接口卡(譯者注:NIC)要求
使用支援DPDK的高端NIC,如Intel XL710 40GbE。
確定每個NIC都刷了最新版本的NVM/固件。
使用PCIe Gen3插槽,例如Gen3 x8或Gen3 x16,因為PCIe Gen2插槽不能為2x10GbE及更高提供足夠的帶寬。 您可以使用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的端口,最好確定這些NIC位于相同的CPU socket上。 下面進一步顯示了如何确定這一點的例子。
#### 8.1.2 BIOS設定
以下是有關BIOS設定的一些建議。 不同的平台會有不同的BIOS命名,是以以下内容主要供參考:
1. 在開始之前考慮将所有BIOS設定重置為其預設設定。
2. 禁用所有節電選項,例如:電源性能調整,CPU P狀态,CPU C3報告和CPU C6報告。
3. 選擇性能作為CPU功耗和性能的政策。
4. 禁用Turbo Boost以確定性能随着核的數量的增加而增加。
5. 将記憶體頻率設定為最高可用數,而不是自動。
6. 測試NIC的實體功能時禁用所有虛拟化選項,并且如果要使用VFIO,請打開VT-d。
#### 8.1.3 Linux引導指令行
以下是關于GRUB引導設定的一些建議:
1. 使用預設的grub檔案作為起點。
2. 通過grub配置預留1G巨頁。 例如,要預留8個1G大小的巨頁:
default_hugepagesz=1G hugepagesz=1G hugepages=8
3. 隔離将用于DPDK的CPU核。 例如:
isolcpus=2,3,4,5,6,7,8
4. 如果它想要使用VFIO,請使用以下額外的grub參數:
iommu=pt intel_iommu=on
### 8.2 運作DPDK之前的配置
1 建構DPDK目标并預留巨頁。 有關更多詳細資訊,請參閱前面關于在Linux環境中使用巨頁的章節。
以下shell指令可能有助于建構和配置:
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
2 使用DPDK cpu_layout應用程式檢查CPU布局:
usertools/cpu_layout.py
或運作lscpu檢查每個socket上的核。
3 檢查您的NIC的ID和相關socket的ID:
List all the NICs with PCI address and device IDs.
例如,假設您的輸出如下所示:
檢查PCI裝置相關的numa節點ID:
通常,0x:00.x位于socket0上,而8x:00.x位于socket1上。注:要獲得最佳性能,請確定核和NIC位于同一socket中。 在上面的示例中,85:00.0位于socket1上,應該由socket1上的核使用,以獲得最佳性能。
4 檢查需要加載哪些核心驅動程式以及是否需要從其核心驅動程式解除綁定網絡端口。 有關DPDK設定和Linux核心要求的更多詳細資訊,請參閱“從源碼編譯DPDK目标”和“Linux驅動程式”章節。
--------------------------------------------------
--------------------------------------------------