1引言node
本文档主要包含INTEL DPDK安装和配置说明。目的是让用户快速的开发和运行程序。文档描述了如何在不深刻细节的状况下在linux应用开发环境上编译和运行一个DPDK应用程序。python
1.1文档总览linux
如下是DPDK文档列表,建议按照文档顺序阅读:ios
注意:以上文档均可以从DPDK源码包的同一个位置上分别下载。c++
2系统必备条件shell
本章讲的是编译DPDK源码包必须具备的环境。编程
注意:若是DPDK要用到intel的89XX系列的网卡平台上,请先翻阅89xx网卡系列的入门手册。ubuntu
2.1X86上BIOS先决条件缓存
对于主要的平台,没有什么特别的BIOS设置才能用DPDK的基本功能。然而总有例外的,对于HPET高精度时钟,能源管理功能,在40g网卡上高性能的小包收发,BIOS设置须要改一下。请看第5章(其它功能的开启)来获取须要作哪些更改的信息。网络
2.2编译DPDK
注意:测试是在Fedora18上,编译安装指令在其它系统上可能不同。在其它linux发行版本上的测试细节请参阅DPDKrelease note。
注意:x86_32应用程序接口只支持最新的debian发行版和13.10以上版本的unbuntu。惟一支持的gcc版本是4.8+。
注意:python须要2.6或者是2.7,在dpdk安装包中有各类各样的帮助脚本。
可选的工具:
2.3运行DPDK程序
要运行dpdk程序,在目标机器上须要一些本地化要求。
2.3.1系统软件
要求:
当前在使用的内核版本能够经过如下命令获取:
uname -r
对于在更早的内核版本上使用DPDK须要的补丁细节,能够看DPDK的Release Notes中的DPDK FAQ。也要注意redhat 6.2和6.3使用的2.6.32内核版本须要用到全部必须得补丁。
c库版本能够经过使用ldd -version命令获取,一个命令使用结果例子以下:
# ldd --version
ldd (GNU libc) 2.14.90
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
在fedora os和其它普通的linux发行版,例如ubuntu,或者是红帽企业版linux,供应商提供的内核配置能够跑大部分DPDK应用。
对于其它内核版本,要使用DPDK必须使一下选项能支持:
2.3.2在linux上使用大页内存
对于要缓存报文的超大内存池的内存分配必须用hugepage,(HUGETLBFS选项在当前容许的内核上必须是支持的,入2.3所说的)使用大页来分配内存,即便只使用少数页面,性能也是可以获得提高的。由于用到更少的页表缓冲条目(TLBs,高速翻译缓存),能够减小翻译虚拟地址到物理地址的时间,若是不用大页,那么用4k的页较高的TLB丢失率会下降性能。实际上还有一个好处就是不会被交换到磁盘上去。
获取DPDK使用的大页内存
分配大页内存最好是在系统启动时或者是在启动后尽早,以便于申请的内存减小碎片,即内存在物理上尽可能是连续的。在内核启动时获取大页内存,须要将一个参数传递给内核。
对于2m的页,仅仅只须要将大页选项发送给内核。例如,申请1024个2m的页:
hugepages=1024
对于其它尺寸的大页内存,例如1g的页,页大小必须明确的指定,也能设置系统的默认大页内存大小。例如申请4g大小的大内存经过4个1g内存页的形式,须要将如下选项发给内核:
default_hugepagesz=1G hugepagesz=1G hugepages=4
注意:在intel的架构机器上cpu支持的大页内存的尺寸取决于CPU标识(这些标示能够经过查看/proc/cpuinfo获取),若是pse存在,那么2m页支持,pdpe1gb存在,则1g页支持。在IBM power架构的机器上,支持16M和16G的页。
注意:64位机器,交付时若是平台支持那天生就支持1g页了。
对于2个socket的NUMA系统,申请的大页内存数在系统启动时通常是从两个socket上平均分配(假定两个socket上都有足够的内存),如上,4g就是一个socket上分出2g内存。
能够看内核源码树的Documentation/kernel-parameter.txt文件获取更多的内核选项细节。
可选项:
2m的页也能够在系统启动后申请,经过echo 内存页数目到/sys/devices/目录下的文件nr_hugepages中。对于单node的系统,使用一下命令获取1024个2m内存页:
echo 1024 > /sys/kernel/mm/hugepages/hugepages_2048kb/nr_huge
在numa的机器上,必须精确的在每一个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
注意:对于1g的大内存页是不可能在系统启动以后申请分配的。
2.3.3 linux环境下Xen Domain0支持
当前的内存管理基于linux内核的大内存页机制,在Xen虚拟机监视器上,大页支持无特权帐户意味着DPDK程序是做为一个普通用户态程序运行。
然而,Domain0不支持大页的,解决这个限制须要,内核模块rte_dom0_mm加入,使得能够经过IOCTL和MMAP来分配和映射内存。
在DPDK中打开Xen Dom0模式
默认状况下,Xen Dom0在DPDK配置文件中是关闭的,要支持Xen Dom0就须要改变配置项CONFIG_RTE_LIBRTE_XEN_DOM0的值为y,那这个功能在编译时就是打开的。
此外,CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID选项也应该设为y,避免万一收到错误的socket id。
加载DPDK rte_dom0_mm模块
在Xen Dom0上跑DPDK程序,rte_dom0_mm模块必须带着参数rsv_memsize选项加载入运行中的内核中。模块能够在DPDK目录下的子目录kmod中找到,加载时使用insmod命令,像下面同样操做(假设咱们当前处于DPDK的根目录下):
sudo insmod kmod/rte_dom0_mm.ko rsc_memsize=X
X的值能够大于4096(MB)
配置DPDK使用的内存
在加载完rte_dom0_mm.ko内核模块后,用户必须配置DPDK使用的内存大小。经过echo 内存页数目到/sys/devices/目录下的内存大小配置文件中。使用以下命令(假设须要2048MB内存):
echo 2048 >/sys/kernel/mm/dom0_mm/memsize-mB/memsize
用户也能够检查当前已经使用了多少内存:
cat /sys/kernel/mm/dom0-mm/memsize-mB/memsize_revd
Xen Domain0不支持NUMA配置,因此–socket-mem选项对它来讲是没用的。
注意:内存大小值不能大于rsv_memsize值
在Xen Domain0上跑DPDK程序
要在Xen Domain0上跑DPDK程序,必须带上额外的选项–xen-dom0
3编译DPDK源码包
3.1安装DPDK和查看源码
首先,解压压缩包并进入DPDK目录:
user@host:~$ unzip DPDK-<version>.zip
user@host:~$ cd DPDK-<version>
user@host:~/DPDK-<version>$ ls
app/ config/ drivers/ examples/ lib/ LICENSE.GPL LICENSE.LGPL Makefile mk/ sc
解压的DPDK目录下有几个子目录:
3.2在目标机器环境下安装DPDK
安装DPDK的结果格式以下(就是在当前目录下回出现一个新目录,目录名格式):
ARCH-MACHINE-EXECENV-TOOLCHAIN
我在redhat上的是x86_64-native-linuxapp-gcc(intel的ICC编译器没用过...,听说在intel的机器上,用icc性能高一些)
生成的文件取决于32/64位安装包和机器上的编译器。能实现的结果能够在DPDK/config中看到。defconfig_ prefix不必用到。
注意:提供的配置文件是根据RTE_MACHINE优化的最优选项集,在配置文件中,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 install T=i686-native-linuxapp-gcc
用gcc编译64位系统:
make install T=x86_64*gcc
同时使用gcc和icc编译64位系统:
make install T=x86_64-*
注意:通配符*表示能够同时生成多个结果。
准备编译而不是编译它,例如,配置被改变了须要在编译前make一下,使用make config T=<target>命令:make config T=x86_64-native-linuxapp-gcc
提示:任意一个使用到的内核模块,如igb_uio,rte,必须在目标机器上同一个运行的内核上编译。若是你的DPDK不是要装在本机,那么编译前须要将RTE_KERNELDIR指向须要安装的机器的内核版本的一个拷贝。
晕:忘了保存了........,再来一遍
一旦环境配置好了,那么进入配置的目录修改代码并编译。用户若是要修改编译时的配置,那么修改安装目录下的.config文件。它是安装根目录下的config目录中的defconfig文件的一个拷贝。
cd x86_64-native-linuxapp-gcc
vi .config
make
此外,make clean命令能够清除以前编译产生的文件,以便从新编译。
3.3查看安装完成的DPDK环境目录
一旦编译完成,那么这个DPDK环境目录包含全部的库文件,PMD,全部DPDK应用程序须要用到了DPDK头文件。此外,测试程序和测试PMD程序在对应的build/app目录下,能够用来测试。当前的kmod目录下须要被加载到内核中的木块。
$ ls x86_64-native-linuxapp-gcc
app build hostapp include kmod lib Makefile
3.4加载内核模块实现DPDK用户态IO
跑dpdk程序,对应匹配的uio模块须要加载到运行的内核中。不少状况下,linux内核已经有的uio_pci_generic模块能够提供uio能力,能够经过如下命令加载:
sudo modprobe uio_pci_generic
相对这个正式的方式,DPDK还提供kmod子目录下的igb_uio模块实现这个功能。加载以下:
sudo modprobe uio
sudoi insmod kmod/igb_uio.ko
注意:对于一些缺少对中断支持的设备,例如虚拟设备(VF),igb_uio须要用来替换uio_pci_generic。
从DPDK1.7以上版本提供VFIO支持之后,对于使用VFIO的平台来讲,用不用uio就无所谓了。
3.5在家VFIO模块
运行一个使用VFIO的程序,vfio-pci模块必须加载:
sudo modprobe vfio-pci
固然要使用VFIO,内核也必须支持才行。自动3.6.0内核版本以来都包含有VFIO模块且默认都是加载的,可是最好是看看对应使用的linux发行版本的说明文档以防万一。
哎,用VFIO,内核和BIOS都必须支持且被配置使用IO virtualization(例如 intel@VT-d(bios里面的一个选项)
对于非root用户在跑dpdk程序时,应该赋予相应的权限操做VFIO。能够经过DPDK脚原本实现(在tools目录下,名字是setup.sh)
3.6绑定和解绑网卡从内核模块
自从dpdk1.4版本起,dpdk程序再也不须要自动的解绑全部支持dpdk且内核驱动正在用的网卡。取而代之的是,dpdk程序要用到的网卡必须在程序运行前绑定到uio_pci_generic, igb_uio或者vfio-pci模块。在linux内核驱动控制下的网卡都会被dpdk的pmd忽略,也不会被程序使用。
提示:dpdk将,也是默认,再也不在启动时自动从linux内核驱动解绑每一个网卡。任意一个要被dpdk用到的网卡必须在程序运行前先从linux控制下解绑而后绑定到对应的uio_pci_generic, igb_uio or vfio-pci。
绑定网卡到uio_pci_generic, igb_uio or vfio-pci供dpdk使用,以及将网卡返回给linux系统控制,tools子目录下叫dpdk_nic_bind.py脚本能够提供该功能。这个脚本能够列出当前系统内全部网卡的状态信息,也能够从不一样linux驱动绑定或者解绑网卡,包括uio和vfio模块。下面是一些展现脚本如何使用的例子。对于脚本完整的功能和参数介绍能够经过使用脚本带上-help或者是-usage参数。要注意的是使用dpdk_nic_bind.py脚本前须要将uio或者是vfio加载到内核中。
提示:对于使用VFIO的设备会有一些限制。主要归结于IOMMU分组如何工做。任何虚拟设备就其自己而言均可以使用VFIO,可是对于物理设备要求绑定到VFIO,或者是其中一些绑定到VFIO而另外的不绑定到任何东西上。
若是你的设备是在一个PCI-to-PCI网桥以后,网桥将做为设备的IOMMU组的一部分。因此当设备在网桥以后工做于VFIO,网桥驱动也必须与网桥PCI设备解绑。
提示:任何用户可使用脚本查看网卡状态,解绑和绑定网卡,可是须要root权限。
上面这个xen啊,vfio啊,不是很懂,翻译的不是很清楚,也可能翻译错了,想搞明白仍是看原文吧。
看系统内网卡的状态:
root@host:DPDK# ./tools/dpdk_nic_bind.py --status
Network devices using DPDK-compatible driver
============================================
0000:82:00.0 '82599EB 10-Gigabit SFI/SFP+ Network Connection' drv=uio_pci_generic unused=ixgbe
0000:82:00.1 '82599EB 10-Gigabit SFI/SFP+ Network Connection' drv=uio_pci_generic unused=ixgbe
Network devices using kernel driver
===================================
0000:04:00.0 'I350 Gigabit Network Connection' if=em0 drv=igb unused=uio_pci_generic *Active*
0000:04:00.1 'I350 Gigabit Network Connection' if=eth1 drv=igb unused=uio_pci_generic
0000:04:00.2 'I350 Gigabit Network Connection' if=eth2 drv=igb unused=uio_pci_generic
0000:04:00.3 'I350 Gigabit Network Connection' if=eth3 drv=igb unused=uio_pci_generic
Other network devices
=====================
<none>
绑定网卡eth1,04:00.1(eth1的pci号),到uio_pci_generic驱动:
root@host:DPDK# ./tools/dpdk_nic_bind.py --bind=uio_pci_generic 04:00.1
或者是用这种方式:
root@host:DPDK# ./tools/dpdk_nic_bind.py --bind=uio_pci_generic eth1
恢复设备82:00.0,绑定到原有的内核驱动:
root@host:DPDK# ./tools/dpdk_nic_bind.py --bind=ixgbe 82:00.0
4编译和运行范例程序
本章介绍了如何编译和在DPDK环境下运行程序,也指示了范例程序存在哪里。
注意:本章的部份内容能够在第6章描述的使用安装脚本后操做。
4.1编译范例程序
一旦DPDK环境建立完成(例如x86_64-nativelinuxapp-gcc),包含开发程序须要的全部的DPDK库和头文件。
当在linux下编译一个基于dpdk的程序,下面的两个参数要被导出:
RTE_SDK:指向DPDK安装目录
RTE_TARGET:指向DPDK目的环境目录,就是编译dpdk产生的目录,例如x86_64-nativelinuxapp-gcc
下面是建立helloworld程序的例子,这个是在dpdk linux环境在运行的。这个例子能够在${RTE_SDK}/examples目录下找到。
这个目录包含一个main.c文件。这个文件和dpdk目录下的库结合,调用各类初始化dpdk环境的函数,而后加载每一个core的入口函数(分发程序)运行。(这个我本身明白可是翻译的不清楚,实际就是在dpdk线程上运行一个入口函数,在函数内再根据所在的逻辑核配置跑对应的功能,入rx,tx,fp)。默认编译产生的可执行二进制文件在build目录下。
user@host:~/DPDK$ cd examples/helloworld/
user@host:~/DPDK/examples/helloworld$ export RTE_SDK=$HOME/DPDK
user@host:~/DPDK/examples/helloworld$ export RTE_TARGET=x86_64-native-linuxapp-gcc
user@host:~/DPDK/examples/helloworld$ make
CC main.o
LD helloworld
INSTALL-APP helloworld
INSTALL-MAP helloworld.map
user@host:~/DPDK/examples/helloworld$ ls build/app
helloworld helloworld.map
注意:在上面的例子中,helloworld是在dpdk目录框架下。然而也有可能它再也不dpdk目录下以保证dpdk的完整。在下面的例子中,helloworl程序就是从dpdk目录下将helloworld拷贝到一个新的目录下:
user@host:~$ export RTE_SDK=/home/user/DPDK
user@host:~$ cp -r $(RTE_SDK)/examples/helloworld my_rte_app
user@host:~$ cd my_rte_app/
user@host:~$ export RTE_TARGET=x86_64-native-linuxapp-gcc
user@host:~/my_rte_app$ make
CC main.o
LD helloworld
INSTALL-APP helloworld
INSTALL-MAP helloworld.map
4.2运行一个范例程序
提示:uio驱动和大页内存必须在程序运行前设置。
提示:每一个程序使用的网卡必须绑定到内核对应的驱动,实际就是咱们家在到内核的dpdk内核模块,如igb_uio等,如3.5所写的,这个动做也要在程序运行前执行。
程序是和dpdk目标环境下的环境抽象层库链接,后者提供了每一个dpdk程序通用的一些选项。
下面是须要提供给eal的参数列表:
./rte-app -c COREMASK -n NUM [-b <domain:bus:devid.func>] [--socket-mem=MB,...] [-m MB] [-r NUM]
EAL选项以下:
-n和-c是必须得,其它都是可选项
拷贝可执行程序到目的机器上,以下运行程序(假设每一个socket有4个内存通道,使用0-3核跑该程序):
user@target:~$ ./helloworld -c f -n 4
注意:选项-proc-type和-file-prefix EAL用于跑多个dpdk程序,能够看《dpdk范例程序使用手册》中的多进程范例程序一章和dpdk开发手册获取更多细节。
4.2.1程序使用的逻辑核
对于dpdk程序,参数coremask是必须有的。每一个bit的掩码都对应linxu展现的逻辑核编号。这些逻辑核编号对应具体得NUMA上的物理核心,不一样的平台会不一样,建议在不一样的平台上运行不一样的例子要考虑选择使用的core的分布。
运行dpdk程序初始化EAL时,会将使用的逻辑核和对应的socket打印出来。这些信息也可用经过查看/proc/cpuinfo来获取,例如,执行 cat /proc/cpuinfo,显示的physical id代表了每一个核所属的cpu插槽。这个在咱们弄明白逻辑核和socket的映射关系时颇有用。
注意:更多的逻辑核分布的拓扑结构视图能够经过使用lstopo获取。在Fedora上,该命令可能安装了,像这样运行:
sudo yum install hwloc
./lstopo
提示:在不一样的主板上布局不一样,逻辑核的分布也会不一样,咱们须要在选取程序使用的逻辑核以前检查一下
4.2.2程序使用的大页内存
在程序运行时,使用分配的数量的大页内存(就是你分配多少就用多少了,而不是按需去整),这是在没有指定参数-m和-socket-mem时程序在启动时自动执行的。
若是程序使用-m和-socket-mem指定具体的内存数超出时,程序就会挂掉。然而,程序要求使用的内存比分配保留的大页内存数小,特别是用-m选项指定时,程序也可能会挂掉。原有以下:假设如今系统在socket0和socket1上各有1024个2M的大内存页。若是用户申请使用128M内存,那64个页可能不知足如下限制:
-socket-mem选择用于在特定的socket上申请指定数目的内存页。使用-socket-mem带上每一个socket申请的内存数实现。例如,使用-socket-mem=0,512,意味着只在socket1上分配512m内存。一样的,在4个socket的机器上,从socket0和socket2上分配各1g内存,参数应该是-socket-mem=1024,0,1024.在其它没有明确指定的cpusocket上不会分配内存,如socket3.若是dpdk在每一个socket上不能申请到足够的内存,EAL就会初始化失败。
4.3其它的范例程序
其它的例子程序在${RTE_SDK}/examples目录下。这些程序的建立和运行与本手册中其它章节描述的差很少。另外就是看《dpdk范例程序使用手册》看具体每一个程序的描述信息,编译和执行时的特殊指令,以及一些代码的注释说明。
4.4另外的测试程序
除此以外,有两个程序在库建立时也建立了。源文件在DPDK/app下,在测试和测试pmd时调用。能够在库建立完成后,在build/app下找到。
测试程序提供了DPDK各类功能的多种测试。
PMD测试程序提供了一些不一样的包收发测试和像如何使用INTEL® 82599万兆网卡的FLow Director这类特征的例子。
5打开其它功能
5.1高精度时钟功能HPET
5.1.1BIOS支持
要使用HPET那么平台的BIOS必须是支持的,不然使用默认的TSC。通常状况下,开机时按F2能够进入bios设置。用户能够选择HPET选项。在intel的Crystal Forest平台的BIOS上,路径是Advanced -> PCH-IOConfiguration -> High Precision Timer -> (Change fromDisabled to Enabled if necessary).
在系统重启后,用下面的指令确认是否打开HPET:
# grep hpet /proc/timer_list
若是没啥返回,HPET在BIOS上确定打开了,每次在重启后执行上述命令。
5.1.2linux内核支持
dpdk使用平台的HPET经过映射时间戳计时器到用户地址空间,诸如此类的,就须要内核的HPET_MMAP选项打开。
提示:在Fedora上,和其它的注入unbuntu发现版上,HPET的内核选项默认是关闭的。在将选项修改后在编译内核,请经过查看发行版文档来获取确切的指令。
5.1.3在DPDK中打开HPET
默认状况下,DPDK的配置文件中HPET支持选项是禁用的。要使用HPET,那么CONFIG_RTE_LIBEAL_USE_HPET选项须要设置成y,会在编译时使用HPET配置。
应用程序要使用rte_get_hpet_cycles() 和rte_get_hpet_hz()这两个接口,使用HPET最为rte_timer库的默认时间源。API rte_eal_hpet_init()须要在程序初始化时调用。这个API的调用确认HPET是可使用,返回错误值则说明不能用。例如,若是内核的HPET_MMAP是关闭的。程序能够决定采起什么动做,若是HPET在运行时不能用。
注意:程序要使用时间API,可是明确HPET是不能用时,建议使用rte_get_timer_cycles() and rte_get_timer_hz()代替HPET相关的API。这两个API使用的不是TSC就是HPET,取决于程序是否调用了rte_eal_hpet_init(),作了就看系统是否在运行时支持了。
5.2非root权限下运行dpdk程序
尽管基于dpdk的程序能直接使用到网卡和其它硬件资源,只须要一点小的权限调整便可跑起来而不是做为root用户使用。要实现这些,文件的全部者或者是权限要调整以便确保linux用户帐号可以使用dpdk程序:
注意:在一些安装的linux上,会默认建立一个大页的挂载点/dev/hugepages
5.3电量管理和省电功能
要用到dpdk的电源管理功能就要求该平台的bios支持加强型intel SpeedStep®技术,不然,sys文件/sys/devices/system/cpu/cpu0/cpufreq就不会存在且cpu平率调整的电源管理也不恩可以用。查阅相关的bIOS文档看如何实现吧
举例说明,在一些intel平台上,Enhanced IntelSpeedStep® Technology在BIOS的路径是:
Advanced->Processor Configuration->Enhanced Intel SpeedStep® Tech
此外,为了电源管理C3和C6也须要打开。C3和C6路径以下:Advanced->Processor Configuration->Processor C3 Advanced->ProcessorConfiguration-> Processor C6
5.4使用linux的cpu核心隔离来减小上下文切换的开销
当DPDK程序线程固定在系统的摸一个核上运行时,linux调度器可能会将其它的任务调度到该核上运行。为了防止其它负载调度到dpdk使用的核上,须要使用linux内核参数isolcpus来将这些核从linux调度器中隔离开。
例如,若是dpdk程序跑在逻辑核2,4,6上,下面的这个参数须要加到内核选项(就是那个grub文件)中:
isolcpus=2,4,6
5.5 加载kni模块
要跑dpdk KNI例子程序,须要额外加载一个模块kni。在dpdk编译目录下的kmod中,和加载igb_uio同样,使用ismod加载:
#insmod kmod/rte_kni.ko
注意:请看DPDK范例使用手册的KNI示例章节。
5.6经过intel的VT-d虚拟化技术实现IOMMU直接传输跑dpdk
要让linux内核支持intel® VT-d,须要打开如下内核选项:
• IOMMU_SUPPORT
• IOMMU_API
• INTEL_IOMMU
此外,要跑使用intel VT-d技术的dpdk程序,在使用igb_uio驱动时必须带上iommu=pt参数。这会让直接内存访问从新映射。若是内核参数NTEL_IOMMU_DEFAULT_ON没有设置,那么内核参数intel_iommu=on也必须使用。这是为了确保intel IOMMU按照预期初始化。
请注意当强制在igb_uio,vfio-pci驱动上使用iommu=pt,确实能够同时使用iommu=pt and iommu=on。
5.740g网卡上小包的高性能处理
最新版本的固件镜像解决了性能加强的问题,固件更新能够获取更高的处理性能。跟本地的intel工程师联系固件更新。支持固件版本FVL3E的基本驱动将在下一个dpdk版本中整合到一块儿,当前能用到的版本是4.2.6
5.7.1 打开Extended Tag和设置Max Read Request Size
PCI的extended_tag和max_read_request_size对40g网卡的小包处理性能有巨大的影响。打开extended_tag和设置max_read_request_size为小尺寸例如128字节会对小包的处理性能提高有恒大的帮助。
CONFIG_RTE_PCI_CONFIG
CONFIG_RTE_PCI_EXTENDED_TAG
CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE
5.7.2 使用16字节大小的rx描述符
i40e的PMD支持16和32字节大小rx描述符,16个字节能够在小包处理性能上提供帮助。要使用16字节的须要修改配置文件中的配置项CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC。
5.7.3高性能和包延迟权衡
因为硬件设计的缘由,每一个包描述符的回写是须要网卡内部的中断型号来实现。最小时间间隔的中断信号能够经过配置文件的CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL配置,编译生效。尽管有默认配置,用户能够考虑性能或者是包处理延迟来调整这个参数。
6快速启动脚本
tools目录下的setup.sh脚本能够帮助用户完成如下任务:
那些步骤完成后,用户须要编译本身的程序并链接建立的dpdk EAL库。
6.1脚本的使用
setup.sh脚本能够暗转给必定的顺序使用,每一步都给说明方便用户完成想要的任务。下面是每一步骤的简短说明:
step1:建立dpdk库
最开始,用户表虚选择须要建立的dpdk目标类型和建立库是用到的编译选项。
用户必须先有全部的连接库,模块,更新和编译安装,如前面章节中介绍的。
step2:安装环境
用户配置linux系统环境以支持运行dpdk程序。大页能够在numa或非numa系统中创建。任何存在的大页都会被弄走。要用到的内核模块也会在这是插入,dpdk用的网卡端口也会绑定到这个模块。
step3:运行程序
一旦上述步骤完成,用户可能要运行测试程序。测试程序容许用户运行一系列的dpdk功能测试。testpmd测试程序则是测试收发包。
step4:检查系统
这一步提供一些工具查看大页的状态信息
step:系统还原
最后一步是将系统还原到初始的状态。
6.2用例
下面的步骤是展现如何使用setup.sh脚本。脚本的运行须要使用source命令,执行前脚本的一些选项提示用到的值。
提示:setup.sh脚本要运行在root权限下。
user@host:~/rte$ source tools/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-ivshmem-linuxapp-gcc
[5] x86_64-ivshmem-linuxapp-icc
[6] x86_64-native-bsdapp-clang
[7] x86_64-native-bsdapp-gcc
[8] x86_64-native-linuxapp-clang
[9] x86_64-native-linuxapp-gcc
[10] 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驱动的示例:(感受不对,25应该按上面说的是卸载驱动啊,2.1没用过,等后面翻译开发手册时再试试吧)
Option: 25
Unloading any existing DPDK UIO module
Loading DPDK UIO module
在numa系统中建立大页的示范。在每一个node上分配1024个2m内存页。结果就是程序应该在启动时带上-m 4096参数使用这些内存(实际上即便不提供-m选项,dpdk程序也会自动使用这些内存)
注意:若是显示提示用户删除临时文件,输入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>>
6.3应用程序
一旦用户setup.sh脚本运行过,EAL建立了,大页也搞好了。就能够建立和运行本身的程序了或者是提供的例子程序。
下面是运行/exaples下的helloword程序示例,使用的是0-3核:
rte@rte-desktop:~/rte/examples$ cd helloworld/rte@rte-desktop:~/rte/examples/helloworld$ makeCC main.oLD helloworldINSTALL-APP helloworldINSTALL-MAP helloworld.maprte@rte-desktop:~/rte/examples/helloworld$ sudo ./build/app/helloworld -c 0xf -n 3[sudo] password for rte:EAL: coremask set to fEAL: Detected lcore 0 as core 0 on socket 0EAL: Detected lcore 1 as core 0 on socket 1EAL: Detected lcore 2 as core 1 on socket 0EAL: Detected lcore 3 as core 1 on socket 1EAL: Setting up hugepage memory...EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0add800000 (size = 0x200000)EAL: Ask a virtual area of 0x3d400000 bytesEAL: Virtual area found at 0x7f0aa0200000 (size = 0x3d400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9fc00000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9f600000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9f000000 (size = 0x400000)EAL: Ask a virtual area of 0x800000 bytesEAL: Virtual area found at 0x7f0a9e600000 (size = 0x800000)EAL: Ask a virtual area of 0x800000 bytesEAL: Virtual area found at 0x7f0a9dc00000 (size = 0x800000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9d600000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9d000000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9ca00000 (size = 0x400000)EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0a9c600000 (size = 0x200000)EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0a9c200000 (size = 0x200000)EAL: Ask a virtual area of 0x3fc00000 bytesEAL: Virtual area found at 0x7f0a5c400000 (size = 0x3fc00000)EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0a5c000000 (size = 0x200000)EAL: Requesting 1024 pages of size 2MB from socket 0EAL: Requesting 1024 pages of size 2MB from socket 1EAL: 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 1hello from core 2hello from core 3hello from core 0