Linux环境下DPDK中文入门文档.docx
《Linux环境下DPDK中文入门文档.docx》由会员分享,可在线阅读,更多相关《Linux环境下DPDK中文入门文档.docx(35页珍藏版)》请在冰点文库上搜索。
Linux环境下DPDK中文入门文档
Linux环境下DPDK中文入门文档
Release17.02.0
Linux环境下DPDK入门...1
1 引言...2
2 资料集...2
3 系统需求...2
3.1 x86平台的先决条件BIOS设置...2
3.2 编译DPDK.3
3.3 运行DPDK程序...3
4 编译DPDK源码...5
4.1 安装DPDK和浏览源码...5
4.2 安装DPDK目标(target)开发环境...6
4.3 浏览安装好的DPDK环境target.6
4.4 加载DPDK用户态IO模块...7
4.5 加载VFIO模块...7
4.6 从核模块绑定和解绑网卡...7
5 编译和运行例子程序...8
5.1 编译例子程序...8
5.2 运行例子程序...9
5.2.1 程序使用的逻辑核...9
5.2.2 程序使用的大页存...10
5.3 其它例子程序...10
5.4 其它的测试程序...10
6 开启其它功能...10
6.1 高精度定时器(HPET)功能...10
6.1.1 BIOS支持...10
6.1.2 linux核支持...11
6.2 非root用户运行DPDK程序...11
6.3 电源管理和省电功能...11
6.4 使用DPDK的CPU亲和性减少上下文切换的开销...12
6.5 加载DPDKKNI核模块...12
6.6 使用linuxIOMMU透传来在INTELVT-d虚拟化环境下运行DPDK.12
6.7 40G网口高性能小包处理...12
6.7.1 使用16个字节的RX描述符...12
6.7.2 高性能和报文时延间的均衡...12
7 快速安装启动脚本...12
7.1 脚本结构...13
7.2 用例...13
7.3 应用程序...15
8 怎么在intel平台上获得网卡的最好性能...17
8.1 硬件和存需求...17
8.1.1 网卡需求...18
8.1.2 BIOS设置...18
8.1.3 Linux核启动参数...18
8.2 运行DPDK前的配置...18
8.3 获取intel网卡的最好性能例子...19
1 引言
文档是安装配置DPDK操作说明,旨在帮助客户快速上手和运行程序。
文档介绍了在linux开发环境下如何编译和运行DPDK程序,但是并不深入细节。
之前曾经尝试着翻译来着,当时因为要离职,一时兴起就想着翻译,翻译的太烂,现在重新翻译,一方面是方便新入职的同事能够快速入门,另外一方面是现在工作的需要,还有一方面是学习KVM想休息一下,看存那块弄得头昏脑胀,而且后面的例子会涉及到虚拟话那块的。
下一个将翻译样例那本书(以及在自己机器上运行可能遇到的问题),同时会参杂着介绍开发者手册中的一些个人理解。
2 资料集
下面列出了所有DPDK文档资料的建议读取顺序:
l 版本说明:
提供了各个版本相关的信息,包括支持的特性,限制,修复的bug,出现的问题等等。
也对频繁提到的问题以FAQ的方式做了回答。
l 入门手册(本文的):
讲述了如何安装配置DPDK;意在帮助开发者快速上手和运行程序。
l 开发者手册:
n 软件架构和(通过例子)在linux环境下使用它
n DPDK的容包括构建系统(包括在DPDK根目录下构建开发环境和程序使用的命令)和移植程序指南。
n 在已有软件和要新开发的软件中需要考虑到的优化。
还提供了一个专有术语表。
l API索引:
提供了DPDK函数,数据结构和其它开发用到的结构体的详细信息。
l 例用户手册:
介绍了一系列的例程序。
每一个章节介绍一个程序,展示程序的特殊功能,说明如何编译,运行和使用例程序。
3 系统需求
本章介绍了编译DPDK需要的安装包。
注意:
如果DPDK要运行在intel89xx系统通讯芯片平台,请翻阅对应该系列的linux入门手册。
3.1 x86平台的先决条件BIOS设置
对于主流的平台,使用DPDK的基本功能并不需要专门的BIOS设置,然而,对于额外的功能像HPET(高精度定时器),电量管理功能,以及在40G网卡上高性能小包处理,需要修改BIOS设置。
修改设置的详细信息见第六章。
3.2 编译DPDK
需要的工具:
注意:
已经在Fedora18上测试运行过,在其它系统上安装命令和需要的安装包可能不一样,要知道其它版本linux发行版测试详细的细节,请查看DPDK版本说明。
l GNUmake
l coreutils:
cmp,sed,grep,arch,等等。
l gcc:
4.9版本或者是所有平台带的更新的版本。
在一些gcc版本中,很多特殊的编译标志和标志默认是打开的,会影响到性能(比如,-fstatck-protector)。
请查阅对应版本的文档和执行gcc–dumpspecs。
l libchreaders,通常打包成gcc-multilib(intel64位架构上是glibc-devel.i686/libc6-dev-i386;glibc-devel.x86_64/libc6-dev,IBMpower架构则是glibc-devel.ppc64)
l 编译核模块需要的核头文件和源文件(kernel-devel.x86_64;kernel-devel.ppc64)
l 在64位机器上编译32位程序而外需要的库:
n glibc.i686,libgcc.i686,libstdc++.i686andglibc-devel.i686forInteli686/x86_64;
n glibc.ppc64,libgcc.ppc64,libstdc++.ppc64andglibc-devel.ppc64forIBMppc_64;
注意:
x86_x32ABI库旨在ubuntu13.10以上版本或者最新Debian版本上支持。
只支持gcc4.9+版本。
l python,要使用dpdk安装包中各种帮助脚本必需的python版本2.7+或者是3.2+。
其它的工具:
l intel编译器icc:
需要安装额外的库。
在编译器安装文档看中icc安装说明。
l IBMpowerlinux高级工具链:
这是一系列的开源开发工具和运行时库,能够让用户用到IBM最新的power硬件特性。
要安装的话看IBM的官方安装文档。
l libpcap头文件和库(libpcap-devel)编译和使用基于libpcap的轮询驱动。
这个驱动默认是禁用的,可以通过修改编译时的配置文件参数CONFIG_RTE_LIBRTE_PMD_PCAP=y来打开。
l libarchive头文件和库在单元测试用打开源文件用到。
3.3 运行DPDK程序
要运行DPDK程序,在目的机器上需要一些定制化的东西。
3.3.1系统软件
要求:
l 核版本>=2.6.34:
通过命令uname–r查看核版本号
l glibc>=2.7(要用到cpuset特性):
可以通过命令ldd–version命令查看gcc版本号
l 核配置
在Fedora操作系统和其它通用发行版,例如Ubuntu,红帽企业版linux,发行商提供的核配置基本可以跑绝大多数DPDK程序。
对于在其它核上构建DPDK,下面几个选项需要能支持:
n UIO(用户态IO)
n HUGETLBFS(大页存)
n PROC_PAGE_MONITOR支持
n HPET和HPET_MMAP配置项必须打开,如果用到HPET,具体细节看第六章。
3.3.2在linux环境下使用大页存
对于大的报文存池存分配,大页存是必须的。
(前一章说过运行的核必须支持大页存)。
使用大页存来分配,即使是小部分页要用到,性能也能够得到提升。
减少了TLBmiss,对应就减少了虚拟地址转物理地址的时间。
使用小页4K存页,很高频率的TLBmiss发生会导致性能低下。
申请大页给DPDK使用
大页存的分配最好是在系统启动时或者是尽量在系统启动后越早越好,这样可以减少分配的物理存页物理地址碎片化。
申请大页存需要在核启动时传递一个命令行参数。
对于2MB存页,分配1024个2MB存页参数如下:
hugepages=1024
其它尺寸的大存页,例如1G页,必须指定申请的存页个数和默认存页的大小。
例如分配4个1G的存页,需要指定的参数如下:
default_hugepagesz=1Ghugepagesz=1Ghugepages=4
注意:
大页存的尺寸是CPU支持的大小来决定的。
intel的机器上通过查看CPUflags来查看支持的大页存尺寸。
比如pse代表支持2MB的存页,pdpe1gb代表支持1G存页。
在IBMpower架构机器上,支持大页存尺寸为16MB和16GB。
注意:
对于64位的应用,如果平台支持,建议使用1G存页。
在双插槽的NUMA系统中,申请的大页存一般会平均在两个socket上分配(假定两个socket都有足够的存)。
可以看linux核源码树中Documentation/kernel-parameters.txt获取更多核选项的细节。
备选项:
对于2M的页,可以在系统启动后申请分配。
echo想要分配的大页存页个数到/sys/devices目录下的nr_hugepages文件。
对于单NUMA(非NUMA)节点的系统,如下命令所示(假设需要1024个2M页):
echo1024>/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
在一个NUMA机器上,分别在不同node上分配指定数目的存页:
echo1024>/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo1024>/sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
注意:
1G的存页在系统启动后是无法申请。
DPDK使用大页
一旦申请到大页存,要想其被DPDK使用到,执行以下步骤:
mkdir/mnt/huge
mount-thugetlbfsnodev/mnt/huge
要想是挂载即使是重启也永久有效,需要把下面一行加到/etc/fstab文件中:
nodev/mnt/hugehugetlbfsdefaults00
1GB存页,必须在挂载的时候将存页的大小作为参数指定:
nodev/mnt/huge_1GBhugetlbfspagesize=1GB00
3.3.3LINUX环境下XenDomain0支持
现有的存管理基于linux核的大页机制。
在Xen虚拟机管理器上,大页存对非特权域(DomainU)的支持意味着DPDK在客户机上可以像普通机器上一样跑。
然而,特权域(domain0)并不支持大页存。
需要插入新的核模块rte_dom0_mm以便绕过这个限制来申请和映射大页存,通过ioctl来申请,mmap来映射。
开启DPDK对XenDom0支持
默认情况下,XenDom0模式支持在DPDK的build配置文件中是禁用的。
要想支持XenDom0,配置项CONFIG_RTE_LIBRTE_XEN_DOM0需要在编译时改成y。
此外,配置项CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID也必须置成y,以防万一收到错误的socketID。
加载rte_dom0_mm模块
要在XenDom0中跑dpdk程序,rte_dom0_mm模块必须带上rsv_memsize参数加载到运行的核中。
可以在编译的DPDK目标目录的子目录中找到该模块。
该模块的加载如下使用insmod命令(假设当前处于DPDK编译的目标目录下):
sudoinsmodkmod/rte_dom0_mm.korsv_memsize=X
X的值可以大于4095MB。
配置DPDK使用的存
在rte_dom0_mm.ko模块加载完成后,用户必须配置DPDK使用的存。
将需要的存大小echo到/sys/devices/目录下的memsize文件中即可。
使用如下命令(假设需要2048MB存):
echo2048>/sys/kernel/mm/dom0-mm/memsize-mB/memsize
用户也可以检查已经使用了多少存:
cat/sys/kernel/mm/dom0-mm/memsize-mB/memsize_rsvd
XenDom0不支持NUMA配置,所以参数--socket-mem对于XenDom0是无效的。
注意:
存大小值不能超过rsv_memsize值。
在XenDomain0中运行DPDK程序
要跑DPDK程序需要额外提供一个命令行参数--xen-dom0。
4 编译DPDK源码
注意:
本章写的部分安装过程也可以通过后续<快速安装脚本>一章中描述的脚本实现。
4.1 安装DPDK和浏览源码
首先,解压压缩包并移动到解压的DPDK源码目录:
tarxJfdpdk-.tar.xz
cddpdk-
DPDK包含以下几个子目录:
l lib:
DPDK库的源码
l drivers:
DPDK轮询驱动的源码
l app:
DPDK应用程序的源码(自动化测试)
l examples:
DPDK应用程序样例源码
l config,buildtools,mk:
框架相关的Makefiles,脚本和配置文件
4.2 安装DPDK目标(target)开发环境
DPDKtarget格式是:
ARCH-MACHINE-EXECENV-TOOLCHAIN
详解:
l ARCH可以是:
i686,x86_64,ppc_64
l MACHINE可以是:
native,power8
l EXECENV可以是:
linuxapp,bsdapp
l TOOLCHAIN可以是:
gcc,icc
将要被安装的target环境取决于要安装的机器上的包是32位还是64位。
可以编译产生的target在DPDK/config目录下定义了。
不要用defconfig_前缀,就是编译的时候不要带上这个前缀。
注意:
配置文件是RTE_MACHINE下的最优配置集合。
在配置文件中,RTE_MACHINE被定义为native,意味着这是针对本机环境下最佳优化的编译。
对于这些设置的更多信息,可以采用的值,看DPDK开发者手册。
当使用ICC编译器时,下面的命令分别对应32位和64位环境使用。
注意这个shell脚本更新$PATH环境变量,因此换个会话就失效了。
编译安装的目录可能是不同的:
source/opt/intel/bin/iccvars.shintel64
source/opt/intel/bin/iccvars.shia32
安装和生成target,在DPDK的根目录下使用makeinstallT=命令。
例如,使用icc编译64位target:
makeinstallT=x86_64-native-linuxapp-icc
使用gcc编译32位的:
makeinstallT=i686-native-linuxapp-gcc
只是做创建target的准备,而不是编译,例如,在编译之前需要手动修改配置文件的,使用命令makeconfigT=:
makeconfigT=x86_64-native-linuxapp-gcc
警告:
任何核模块,比如igb_uio,kni等,必须编译时的核和要运行时的核一致。
如果DPDK不是在编译产生的目标机器上运行,RTE_KERNELDIR环境变量必须指向要运行target机器对应核版本。
一旦目标环境创建完成,用户可能需要进入目标环境目录,修改源码并重新编译。
用户也可能修改编译时的DPDK配置项,通过编辑build目录下的.config文件(这个文件是从顶层目录的config目录下defconfig文件拷贝到本地来的):
cdx86_64-native-linuxapp-gcc
vi.config
make
此外,makeclean命令可以清除所有之前编译留下的文件。
4.3 浏览安装好的DPDK环境target
一旦target创建完成就包含所有的苦,包括轮询驱动,和用户程序编译需要的DPDK环境头文件。
此外,test和testpmd程序在build/app目录下创建完成,可用于测试。
kmod目录下包含需要加载到核中的几个核模块。
4.4 加载DPDK用户态IO模块
运行DPDK程序,一个合适的uio模块需要加载到运行中的核。
在很多例子中,标准的uio_pci_genericLINUX核模块可以提供用户态驱动能力。
该模块加载如下:
sudomodprobeuio_pci_generic
和上述不同的是,DPDK提供了igb_uio模块来实现(在kmod目录下):
sudomodprobeuio
sudoinsmodkmod/igb_uio.ko
注意:
对于缺乏对传统中断支持的设备,比如VF设备,igb_uio模块可能需要被uio_pci_generic替换掉。
在DPDK1.7之前版本提供了对VFIO的支持,在支持VFIO的平台上UIO就不是必须的了。
4.5 加载VFIO模块
使用VFIO的DPDK应用程序,vfiopci模块必须加载:
sudomodprobevfio-pci
需要注意的是要使用VFIO,你的核必须支持才行。
VFIO核模块在LINUX核3.6.0版本之后就囊括经来了,默认是有的。
然而,请翻阅linux发行版文档确定一下。
使用VFIO,BIOS和核都必须支持,BIOS需要打开支持虚拟化的配置选项(例如Intel?
VT-d).
在非特权用户下运行DPDK程序,要正确的操作VFIO,需要建立正确的权限设置。
这个可以通过DPDK安装脚本实现(dpdk-setup.sh,位于usertools目录下)
4.6 从核模块绑定和解绑网卡
在1.4版本,DPDK程序不再自动解绑所有支持DPDK的网口,当网口绑定在核驱动上且正在运行时。
取而代之的是,DPDK程序在运行前,必须将使用的所有网口绑定到uio_pci_generic,igb_uio或者是vfio-pci模块上。
任何linux控制下的网口将被DPDK轮询驱动忽略,不能被DPDK程序使用。
警告:
DPDK默认不再在启动时自动解绑核驱动管理的网口。
任何PDDK程序使用的网口必须在程序运行前解除linux控制,绑定到对应的驱动上(uio_pci_generic,igb_uio或者是vfio-pci).
将绑定到DPDK的网口解绑并交给linux控制,可以使用usertool子目录下的dpdk_nic_bind.py脚本。
这个脚本可以展示当前系统中所有网口的状态,可以将其从不同的核模块间解绑和绑定,包括uio和vfio模块。
下面是使用脚本的例子。
要想获取脚本的全部使用描述和参数,可以带上—help或者是—usage参数启动脚本。
注意,uio或者是vfio核模块需要在运行dpdk-nic-bind.py脚本之前加载到核中。
查看系统中所有网口的状态:
./usertools/dpdk-devbind.py--status
NetworkdevicesusingDPDK-compatibledriver
============================================
0000:
82:
00.0‘82599EB10-GbENIC‘drv=uio_pci_genericunused=ixgbe
0000:
82:
00.1‘82599EB10-GbENIC‘drv=uio_pci_genericunused=ixgbe
Networkdevicesusingkerneldriver
===================================
0000:
04:
00.0‘I3501-GbENIC‘if=em0drv=igbunused=uio_pci_generic*Active*
0000:
04:
00.1‘I3501-GbENIC‘if=eth1drv=igbunused=uio_pci_generic
0000:
04:
00.2‘I3501-GbENIC‘if=eth2drv=igbunused=uio_pci_generic
0000:
04:
00.3‘I3501-GbENIC‘if=eth3drv=igbunused=uio_pci_generic
Othernetworkdevices
=====================
绑定设备eth1,“04:
00.1”到uio_pci_generic驱动上:
./usertools/dpdk-devbind.py--bind=uio_pci_generic04:
00.1
或者是:
./usertools/dpdk-devbind.py--bind=uio_pci_genericeth1
恢复设备82:
00.0到原始的核驱动上:
./usertools/dpdk-devbind.py--bind=ixgbe82:
00.0
5 编译和运行例子程序
本章讲的是怎么在DPDK环境下编译和运行程序。
也指出了样例程序保存在哪里。
注意:
本章写的部分安装过程也可以通过后续<快速安装脚本>一章中描述的脚本实现。
5.1 编译例子程序
DPDK目标环境目录创建完成(例如x86_64-native-linuxapp-gcc),就包含了创建一个dpdk应用程序需要的库和头文件。
当在linuxDPDK环境下编译程序,下面两个环境遍历必须export:
l RTE_SDK指向DPDK编译安装目录即target所在目录
l RTE_TARGET指向DPDKtarget目录名
下面展示的是运行在linuxDPDK环境下的例子hel