1.DPDK 簡介
DPDK(Data Plane Development Kit)是數(shù)據(jù)平面開發(fā)工具包搅窿,由用于加速在各種CPU架構上運行的數(shù)據(jù)包處理的庫組成。
DPDK需要一定的網(wǎng)卡硬件支持,以Intel為例尝江,支持以下網(wǎng)卡:
e1000 (82540, 82545, 82546)
e1000e (82571, 82572, 82573, 82574, 82583, ICH8, ICH9, ICH10, PCH, PCH2, I217, I218, I219)
igb (82575, 82576, 82580, I210, I211, I350, I354, DH89xx)
ixgbe (82598, 82599, X520, X540, X550)
i40e (X710, XL710, X722, XXV710)
ice (E810)
fm10k (FM10420)
ipn3ke (PAC N3000)
ifc (IFC)
完整的網(wǎng)卡支持列表可在官網(wǎng)查詢:
http://core.dpdk.org/supported/
在Linux上部署DPDK有兩種方式跪妥,一種是通過命令行依次進行配置岳枷,編譯,驅動加載等垒探;另一種是通過DPDK的腳本進行快捷配置和編譯妓蛮。
通過命令行的方式部署,可配置項更多圾叼,可以獲得更佳的性能蛤克,對DPDK的工作環(huán)境也能有更好的熟悉;通過腳本方式部署步驟較少夷蚊,較簡單构挤。
通過腳本部署的教程請移步:
在Linux(CentOS)上部署DPDK------腳本方式
2.DPDK 環(huán)境
該章節(jié)的內容參照自官網(wǎng)的DPDK System Requirements。
2.1 編譯所需的工具和庫
- GNU:
make
惕鼓。 - coreutils:
cmp
,sed
,grep
,arch
, etc. - gcc: versions 4.9 或更新版本筋现。
- libc headers, 即
glibc-devel.x86_64
(以64位數(shù)Intel平臺為例)。 - Linux kernel headers or sources required to build kernel modules. (
kernel - devel.x86_64
;kernel - devel.ppc64
) - 若需要在64位操作系統(tǒng)上編譯32位軟件箱歧,還需要以下工具:
-
glibc.i686
,libgcc.i686
,libstdc++.i686
andglibc-devel.i686
for Intel i686/x86_64; -
glibc.ppc64
,libgcc.ppc64
,libstdc++.ppc64
andglibc-devel.ppc64
for IBM ppc_64;
-
這里需要注意的是kernel-devel
的版本要匹配內核的版本矾飞,可以通過uname -r
查看內核版本號,并通過yum info kernel-devel
查看已安裝或支持的kernel-devel
版本號呀邢。這里查看到我的centos已經(jīng)預裝了kernel-devel
洒沦,版本與kernel版本一致:
uname -r
3.10.0-862.el7.x86_64
yum info kernel-devel
已安裝的軟件包
名稱 :kernel-devel
架構 :x86_64
版本 :3.10.0
發(fā)布 :862.el7
大小 :37 M
源 :installed
kernel頭文件的路徑位于/usr/lib/modules/$kernel-version/kernel
2.2 運行環(huán)境
- Kernel version >= 3.16
- glibc >= 2.7 (for features related to cpuset)
- Kernel configuration,centos提供的配置可運行大多數(shù)DPDK應用驼鹅。
2.3 設置Hugepages
Hugepages是DPDK用于提升性能的重要手段微谓。 通過使用Hugepages森篷,可以降低內存頁數(shù),減少TLB頁表數(shù)量豺型,增加TLB hit率仲智。
在Linux上設置Hugepages有兩種方式:
- 修改Kernel cmdline(推薦)
- 修改sysfs節(jié)點
2.3.1 修改Kernel cmdline(推薦)
通過修改kernel command line可以在kernel初始化時傳入Hugepages相關參數(shù)并進行配置。
具體的操作步驟如下:
- 修改grub文件
修改/etc/default/grub
文件姻氨,在GRUB_CMDLINE_LINUX
中加入如下配置:
該配置表示默認的hugepages的大小為1G钓辆,設置的hugepages大小為1G,hugepages的頁數(shù)為4頁肴焊,即以4個1G頁面的形式保留4G的hugepages內存default_hugepagesz=1G hugepagesz=1G hugepages=4
修改后的grub文件示例如下:GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap default_hugepagesz=1G hugepagesz=1G hugepages=4 rhgb quiet" GRUB_DISABLE_RECOVERY="true"
- 編譯grub配置文件
可以通過命令grub2-mkconfig -o /boot/grub2/grub.cfg
- 重啟
通過reboot
命令重啟前联,隨后可以通過cat /proc/cmdline
查看kernel的command line是否包含之前的配置。
也可以通過cat /proc/meminfo | grep Huge
命令查看是否設置成功娶眷,若設置成功可以看到如下配置:HugePages_Total: 4 HugePages_Free: 4 Hugepagesize: 1048576 kB
DPDK官方建議似嗤,64位的應用應配置1GB hugepages。
這種配置方式的優(yōu)點是可以在系統(tǒng)開機時即配置預留好hugepages届宠,避免系統(tǒng)運行起來后產(chǎn)生內存碎片烁落;另外,對于較大的例如1G pages豌注,是不支持在系統(tǒng)運行起來后配置的伤塌,只能通過kernel cmdline的方式進行配置。
注:對于雙插槽的NUMA系統(tǒng)(dual-socket NUMA system)轧铁,預留的hugepages會被均分至兩個socket每聪,可以通過lscpu
查看CPU信息:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 4
socket(s): 1
NUMA node(s): 1
可見測試主機使用的是單socket的NUMA系統(tǒng)畅形。
2.3.2 修改sysfs節(jié)點
對于2 MB頁面灾挨,還可以選擇在系統(tǒng)啟動后進行分配。 這是通過修改 /sys/devices/
中的nr_hugepages
節(jié)點來實現(xiàn)的狂丝。 對于單節(jié)點系統(tǒng)救斑,若需要1024個頁面果善,可使用如下命令:
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
在NUMA機器上,頁面的需要明確分配在不同的node上(若只有一個node只需要分配一次):
echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
這種配置方式的優(yōu)點是配置簡單系谐,無需編譯巾陕、重啟,但是無法配置1GB這樣的大hugepages纪他。
2.3.3 DPDK使用Hugepages
預留好Hugepages之后鄙煤,想要讓DPDK使用預留的Hugepages,需要進行下述操作:
mkdir /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
可以將這個掛載點添加到/etc/fstab
中茶袒,這樣可以永久生效梯刚,即重啟后也仍然可以生效:
nodev /mnt/huge hugetlbfs defaults 0 0
對于1GB pages,在/etc/fstab
中必須指定page size作為mount選項薪寓。
nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0
添加上面這樣一行內容至/etc/fstab
后并重啟亡资,可以通過df -a
看到掛載成功:
nodev 0 0 0 - /mnt/huge_1GB
3.DPDK 編譯
該章節(jié)的內容參照自官網(wǎng)的DPDK build澜共。
3.1 下載DPDK代碼
可從官網(wǎng)下載最新的穩(wěn)定版或開發(fā)版的DPDK代碼DPDK代碼下載。
然后解壓縮:
tar xJf dpdk-<version>.tar.xz
cd dpdk-<version>
其中DPDK的代碼包含如下部分:
- lib: Source code of DPDK libraries
- drivers: Source code of DPDK poll-mode drivers
- app: Source code of DPDK applications (automatic tests)
- examples: Source code of DPDK application examples
- config, buildtools, mk: Framework-related makefiles, scripts and configuration
3.2 編譯和安裝
想要編譯和安裝DPDK锥腻,需要在DPDK的頂層目錄運行下面運行make install T=<target>
嗦董;或者可以首選運行make config T=<target>
來進行配置,隨后運行make
來編譯瘦黑。
這里的target
的格式為:
ARCH-MACHINE-EXECENV-TOOLCHAIN
其中:
-
ARCH
可以是:i686
,x86_64
,ppc_64
,arm64
-
MACHINE
可以是:native
,power8
,armv8a
-
EXECENV
可以是:linux
,freebsd
-
TOOLCHAIN
可以是:gcc
,icc
這里我們使用gcc來編譯64位DPDK京革,這里最初按照官網(wǎng)的guide使用linux
編譯報錯,后改用linuxapp
:
make install T=x86_64-native-linuxapp-gcc
在編譯的過程中幸斥,若出現(xiàn)頭文件缺失可通過yum
進行安裝匹摇。
編譯完成后,target環(huán)境會在DPDK頂層目錄以x86_64-native-linuxapp-gcc
為文件名創(chuàng)建甲葬,若需要修改配置重新編譯廊勃,可通過修改target目錄下的.config
文件再重新編譯:
cd x86_64-native-linuxapp-gcc
vi .config
make
4.DPDK 驅動加載
該章節(jié)的內容參照自官網(wǎng)的DPDK Linux Drivers。
不同的PMD需要不同的內核驅動程序才能正常工作经窖。 取決于正在使用的PMD供搀,應加載相應的內核驅動程序并綁定到網(wǎng)絡端口。
4.1 UIO
UIO(Userspace I/O)是運行在用戶空間的I/O技術钠至。Linux系統(tǒng)中一般的驅動設備都是運行在內核空間,而在用戶空間用應用程序調用即可胎源。
而UIO則是將驅動的很少一部分運行在內核空間棉钧,而在用戶空間實現(xiàn)驅動的絕大多數(shù)功能。
在許多情況下涕蚤,Linux內核中包含的標準uio_pci_generic模塊可以提供uio功能宪卿。 可以使用以下命令加載此模塊:
sudo modprobe uio_pci_generic
除了Linux內核中包含的標準uio_pci_generic模塊,DPDK也提供了一個可替代的igb_uio模塊万栅,可以在kmod
路徑中找到佑钾。可以通過以下方法加載igb_uio模塊烦粒。
sudo modprobe uio
sudo insmod kmod/igb_uio.ko
如果用于DPDK的設備綁定為uio_pci_generic內核模塊休溶,需要確保IOMMU已禁用或passthrough。 以intel x86_64系統(tǒng)為例扰她,可以在的GRUB_CMDLINE_LINUX
中添加intel_iommu = off
或intel_iommu = on iommu = pt
兽掰。
4.2 VFIO(推薦)
VFIO與UIO相比,它更加強大和安全徒役,依賴于IOMMU孽尽。 要使用VFIO,需要:
- Linix kernel version>=3.6.0
- 內核和BIOS必須支持并配置為使用IO virtualization(例如Intel?VT-d)忧勿。
在確認硬件配置支持的情況下杉女,要使用VFIO驅動綁定到NIC必須先使能iommu瞻讽,否則會導致綁定失敗。具體的現(xiàn)象就是查看或修改sysfs節(jié)點/sys/bus/pci/drivers/vfio-pci/bind
出現(xiàn)io錯誤熏挎,以及dmesg中出現(xiàn):
vfio-pci: probe of 0000:05:00.0 failed with error -22
使能iommu的方法也是修改kernel的command line將iommu=pt intel_iommu=on
傳入速勇,具體步驟:
- 修改grub文件
修改/etc/default/grub
文件,在GRUB_CMDLINE_LINUX
中加入如下配置:iommu=pt intel_iommu=on
- 編譯grub配置文件
可以通過命令grub2-mkconfig -o /boot/grub2/grub.cfg
- 重啟
通過reboot
命令重啟婆瓜,隨后可以通過cat /proc/cmdline
查看kernel的command line是否包含之前的配置快集。
iommu配置成功后,dmesg中會有iommu配置group的log廉白,可以通過dmesg | grep iommu
查看:
[ 0.594500] iommu: Adding device 0000:05:00.0 to group 18
[ 0.594512] iommu: Adding device 0000:06:00.0 to group 19
即表示iommu使能成功个初。
隨后需要調用modprobe
來加載VFIO的驅動:
sudo modprobe vfio-pci
4.3 驅動綁定NIC
上述的UIO和VFIO驅動可以加載一項,也可以全都加載猴蹂。但是在驅動綁定NIC的時候院溺,只能選擇一種驅動綁定到NIC,這里采用VFIO驅動磅轻。
可以調用dpdk路徑下的usertools/dpdk-devbind.py
實用腳本來進行VFIO驅動與NIC綁定珍逸,需要注意的是使用這個腳本進行綁定(bind)動作時是需要root權限的。
可以調用腳本傳入--status
查看當前的網(wǎng)絡端口的狀態(tài):
python usertools/dpdk-devbind.py --status
Network devices using kernel driver
===================================
0000:03:00.0 'I210 Gigabit Network Connection 1533' if=enp3s0 drv=igb unused=vfio-pci *Active*
0000:04:00.0 'I210 Gigabit Network Connection 1533' if=enp4s0 drv=igb unused=vfio-pci *Active*
0000:05:00.0 'I210 Gigabit Network Connection 1533' if=enp5s0 drv=igb unused=vfio-pci
0000:06:00.0 'I210 Gigabit Network Connection 1533' if=enp6s0 drv=igb unused=vfio-pci
可以看到聋溜,當前NIC的狀態(tài)都是Network devices using kernel driver
谆膳,使用的是kernel的igb驅動drv=igb
。
隨后可以調用腳本傳入--bind
將網(wǎng)卡05:00.0
撮躁,也就是enp5s0
綁定到VFIO驅動:
python usertools/dpdk-devbind.py --bind=vfio-pci 05:00.0
再次調用腳本傳入--status
漱病,可以看到:
Network devices using DPDK-compatible driver
============================================
0000:05:00.0 'I210 Gigabit Network Connection 1533' drv=vfio-pci unused=igb
Network devices using kernel driver
===================================
0000:03:00.0 'I210 Gigabit Network Connection 1533' if=enp3s0 drv=igb unused=vfio-pci *Active*
0000:04:00.0 'I210 Gigabit Network Connection 1533' if=enp4s0 drv=igb unused=vfio-pci *Active*
0000:06:00.0 'I210 Gigabit Network Connection 1533' if=enp6s0 drv=igb unused=vfio-pci
設備05:00.0
已經(jīng)配置為drv=vfio-pci
,若想要恢復為kernel默認的igb驅動把曼,則可以繼續(xù)調用腳本:
python usertools/dpdk-devbind.py --bind=igb 05:00.0
至此杨帽,DPDK的部署就算完成了,接下來可以嘗試編譯和運行
基于DPDK的簡單應用了嗤军。
基于DPDK的簡單應用編譯與運行方法可以查看:
編譯和運行DPDK示例程序