linux dpdk 怎样获取流量
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux dpdk 怎样获取流量相关的知识,希望对你有一定的参考价值。
参考技术A dpdk是用户态驱动,网卡绑定dpdk驱动后,开启混杂模式,就可以收发包了。 参考技术B 网络接口没配置好吧,没有IPV4地址,我们通常用的是IPV4,IPV6还没普及,不知你的是什么配置?DPDK快速上手指南(18.02)
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。要使用HP??ET,应将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*
- 如果要使用HP??ET,/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上的路径是:
Advanced
-> Processor Configuration
-> Processor C3 Advanced
-> Processor Configuration
-> 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/
make
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: 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
--------------------------------------------------
--------------------------------------------------
## 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
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)和未知(不存在)。 这与之前的输出一致,表明每个通道都有一个内存条。
#### 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布局:
cd dpdk_folder
usertools/cpu_layout.py
或运行lscpu检查每个socket上的核。
3 检查您的NIC的ID和相关socket的ID:
List all the NICs with PCI address and device IDs.
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节点ID:
cat /sys/bus/pci/devices/0000\:xx\:00.x/numa_node
通常,0x:00.x位于socket0上,而8x:00.x位于socket1上。注:要获得最佳性能,请确保核和NIC位于同一socket中。 在上面的示例中,85:00.0位于socket1上,应该由socket1上的核使用,以获得最佳性能。
4 检查需要加载哪些内核驱动程序以及是否需要从其内核驱动程序解除绑定网络端口。 有关DPDK设置和Linux内核要求的更多详细信息,请参阅“从源码编译DPDK目标”和“Linux驱动程序”章节。
--------------------------------------------------
--------------------------------------------------
以上是关于linux dpdk 怎样获取流量的主要内容,如果未能解决你的问题,请参考以下文章