深入浅出DPDK学习笔记——DPDK编译及使用

DPDK(Data Plane Development Kit)是Intel推出的一个开源工具包,旨在解决虚拟交换机在处理高速数据包时的性能瓶颈问题。常规虚拟交换机由于CPU多任务处理和内存管理效率低下导致性能下降。DPDK通过轻量级库函数和内存管理机制,如环形缓冲区和减少CPU中断,显著提升了软件交换机的性能。本文介绍了DPDK的安装、配置和使用,包括加载内核模块、绑定网卡以及处理常见问题,展示了如何利用DPDK提升OVS等应用的性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

软件(虚拟)交换机性能低下的主要原因是它们未经优化或设计用于处理和交换过高速率的数据包,而DPDK(Data Plane Development Kit, 数据平面开发工具包)则专门解决这个问题。在解释DPDK如何改善这种情况之前,需要回顾常规虚拟交换机存在的局限性。由于虚拟交换机对高速数据包的处理缺乏优化,因而导致数据包处理的过程中的很多步骤都要用到CPU,由于CPU需要处理多任务,因而其可用性(特别是超载的情况下)会出现性能瓶颈的问题。此外,虚拟交换机也无法高效使用系统内存,它们首先将数据包复制到内存缓冲区,然后中断客户端CPU并将数据包复制到客户端内存,最后再从vNIC将数据读取给应用程序。单纯的内存读写所产生的内存分配,去分配以及CPU中断等处理操作都会降低虚拟交换机的性能。
开发DPK的主要目的是为软件处理数据包提供一种优化方式,DPDK是由Intel公司创建的一组库函数和NIC驱动程序。2013年,Intel将DPDK作为开源开发工具包提供给开发者社区,允许开发人员在软件交换机以及利用DPDK提供的微调能力的类似应用程序中使用这些库函数。虽然DPDK对任何希望使用它的软件来说都一视同仁,但是在OVS中的应用较为突出。
DPDK用自己的库函数替换了Linux内核的内置数据平面,DPDK的轻量级库函数采用了非常有效的内存处理机制,即利用环形缓冲区在物理网卡与使用了DPDK的应用程序(如OVS)之间来回传送数据包,从而提高了系统整体性能。为了减少数据包读取所需的CPU中断数,DPDK采用周期性轮询机制,由系统内核定期轮询新数据包。如果数据包速率降至非常低数值,那么就可以切换到中断模式而不是定期轮询模式。通过有效的缓存管理、优化的最少CPU中断数以及其他增强型功能,证实DPDK能够让OVS实现接近原生性能。但是,DPDK的功能特性较少,没有自己的网络协议栈,主要功能就是完成数据包的处理和转发,DPDK与实现网络功能的应用程序结合(如OVS-DPDK),就能提供丰富的功能特性和良好的转发性能。

安装DPDK依赖环境

在这里插入图片描述

为确保DPDK安装成功,程序正常编译使用,安装前可执行如下命令,安装程序依赖。DPDK18.11建议系统内核版本>=3.2,自19.02建议系统内核版本>=3.16。建议参考官方文档说明http://doc.dpdk.org/guides-20.02/linux_gsg/sys_reqs.html
在这里插入图片描述

$ yum update
$ yum install libpcap-devel kernel*

下载并安装DPDK

Git安装

$ git config --global core.autocrlf input
$ git clone -b releases https://github.com/DPDK/dpdk.git
$ git checkout v20.02
# make config T=x86_64-native-linux-gcc && make
./usertools/dpdk-setup.sh

下载源码压缩包编译

$ wget https://github.com/DPDK/dpdk/archive/v20.02.tar.gz
$ tar zxvf v20.02.tar.gz
$ cd dpdk-20.02
# make config T=x86_64-native-linux-gcc && make
$ ./usertools/dpdk-setup.sh

dpdk编译后无igb_uio.ko或安装Insert IGB UIO module失败

自v20.02版本以后,DPDK就默认关闭igb_uio模块。若构建它,需要配置文件选项CONFIG_RTE_EAL_IGB_UIO设置为enabled。并且官方已计划将其移到其他项目。
解决办法:
一是配置文件dpdk/config/common_base中开启该配置CONFIG_RTE_EAL_IGB_UIO=y,注意这个文件是全局配置。如果仅修改局部的编译,可以在编译时各自文件夹dpdk/x86_64-native-linux-gcc/.config文件中对应修改该参数。本文采用v20.02版本,系统内核3.10,可以正常编译出igb_uio.ko文件。(调试DPDK可开启参数CONF_RTE_LIBRTE_CRYPTODEV_DEBUG=y)

$ vi config/common_base
#修改CONFIG_RTE_EAL_IGB_UIO=y
#:wq

二是使用dpdk18.11或之前的版本

$ git tag
$ git checkout v18.11

DPDK加载绑定

载入用户态驱动

启用DPDK用户控件I/O的模块,模块驱动类型就是uio_pci_generic,igb_uio,以及vfio-pci。不同的设备需要不同的内核驱动才能工作正常。因此需要根据使用的设备类型,来加载相应的内核驱动并绑定到网络接口上,可参考官方文档http://doc.dpdk.org/guides-20.05/linux_gsg/linux_drivers.html。
UIO(Userspace I/O)是运行在用户空间的I/O技术,Linux系统中一般的驱动设备都是运行在内核空间,而在用户空间用应用程序调用即可,而UIO则是将驱动的很少一部分运行在内核空间,而在用户空间实现驱动的绝大多数功能!使用UIO可以避免设备的驱动程序需要随着内核的更新而更新的问题。
三种驱动类型的个人理解:UIO驱动(uio_pci_generic,igb_uio)主要作为轻量级内核模块UIO提供给设备,例如uio_pci_generic,映射设备存储到内核空间并注册中断机制。对于缺少传统中断的设备,例如缺少VF虚拟功能,可以采用igb_uio模块替换uio_pci_generic。如果想要比UIO更健壮更安全的内核模块,可以采用vfio-pci,基于IOMMU的安全保护。

$ su
$ modprobe uio
#本文操作环境采用虚拟机CentOS7.6,所以采用igb_uio,也可采用vfio-pci
$ modprobe igb_uio
$ insmod dpdk/x86_64-native-linux-gcc/kmod/igb_uio.ko
#modprobe uio_pci_generic
#modprobe vfio
#modprobe vfio-pci
#也可以采用如下命令
$ ./usertools/dpdk-setup.sh
[45] Insert IGB UIO module
[46] Insert VFIO module
[47] Insert KNI module
#然后选择安装根据提示,选择加载的内核模块
# 如果出现该报错
## ERROR: Target does not have the DPDK UIO Kernel Module.
#      To fix, please try to rebuild target.
# 需要提前载入UIO基础模块
# modprobe uio

驱动绑定网卡

建议使用多网卡,用dpdk接管其他非ssh网卡通道,例如ens34网卡。通过驱动绑定网卡pci端口,-b表示–bind的意思;0000:0b:00.0是当前物理机或虚拟机采用的网卡pci端口号。

#0.查询网卡物理地址
$ lspci |grep Ethernet
#或采用如下命令
$ sudo lshw -class network -businfo
#回显返回02:02.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01),其中02.02.0为设备物理地址。
$ ifconfig ens34 down
$ ./usertools/dpdk-devbind.py -b igb_uio ens34
#或者
$ ifconfig ens34 down
$ ./usertools/dpdk-devbind.py -b igb_uio 0000:02:01.0
#或者
$ ifconfig ens34 down
$ ./usertools/dpdk-setup
#然后选择[51] Bind Ethernet/Baseband/Crypto device to IGB UIO module
#查看网卡信息:
$ ./usertools/dpdk-devbind.py --status
#如修改回普通网卡模式,则使用如下命令
$ ./usertools/dpdk-devbind.py -b e1000 0000:02:05.0
$ ifconfig ens34 up

绑定网卡故障排查及开启Intel-vt-x/vt-d

如果绑定出现问题,通过dmesg|grep -i igb_uio检查错误信息。实验中总是绑定网卡失败错误码-22,表示无效参数。最后证明是驱动不支持网卡类型,或者是DPDK不支持,或虚拟机中需要启动intel-vt-td/vt-d支持。

# 查看虚拟机中是否开启intel-vt-x/vt-d
$ cat /proc/cpuinfo | grep vmx

# 修改系统内核启动参数,重启系统,查看是否开启IOMMU
$ dmesg | grep -e DMAR -e IOMMU
[ 0.000000] DMAR: IOMMU enabled

# 执行如下脚本检查是否支持中断重定向
#!/bin/sh
if [ $(dmesg | grep ecap | wc -l) -eq 0 ]; then
  echo "No interrupt remapping support found"
  exit 1
fi
for i in $(dmesg | grep ecap | awk '{print $NF}'); do
  if [ $(( (0x$i & 0xf) >> 3 )) -ne 1 ]; then
    echo "Interrupt remapping not supported"
    exit 1
  fi
done

# 如果硬件不支持interrupt remapping,需要执行
echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf

这里重点是,一定要启动Intel VT-d/VT-x!!!-22错误一般都是Intel VT-d/VT-x没有开启;
解决方法如下依次列出,读者可以根据情况尝试:开机后按F12进入BIOS界面打开VT-x和VT-d、若虚拟机,点击设置,处理器,并开启VT-x等,若无法打开,需要提高内存分配;有些需要在虚拟机选项上配置,右键单击虚拟机(关机状态)-》设置-》处理器-》虚拟化引擎标签栏中,选中 启动虚拟化。
在这里插入图片描述
有些Linix内核版本可能缺省没有使能CONFIG_INTEL_IOMMU
上述参考来源:
https://blog.51cto.com/14207158/2352319
https://www.cnblogs.com/vancasola/p/9378970.html
https://fd.io/docs/vpp/master/usecases/vhost/vhost.html
https://blog.51cto.com/10017068/2107562

官方文档部分翻译

For some devices which lack support for legacy interrupts, e.g. virtual function (VF) devices, the igb_uio module may be needed in place of uio_pci_generic.
  对于一些缺少传统中断的设备,例如缺少VF虚拟功能,可以采用igb_uio模块替换uio_pci_generic。
If UEFI secure boot is enabled, the Linux kernel may disallow the use of UIO on the system. Therefore, devices for use by DPDK should be bound to the vfio-pci kernel module rather than igb_uio or uio_pci_generic.
  如果开启UEFI安全启动,Linux内核可能不允许使用UIO。因此使用DPDK的设备应该绑定vfio-pci内核模块,而不是igb_uio或uio_pci_generic。
If the devices used for DPDK are bound to the uio_pci_generic kernel module, please make sure that the IOMMU is disabled or passthrough. One can add intel_iommu=off or amd_iommu=off or intel_iommu=on iommu=ptin GRUB command line on x86_64 systems, or add iommu.passthrough=1 on arm64 system.
  如果设备使用DPDK绑定了uio_pci_generic内核模块,请确认关闭IOMMU或直通IOMMU。可以在x86_64系统的GRUB命令行中添加intel_iommu=off或amd_iommu=off或intel_iommu=on iommu=pthuo或在arm64 system系统上添加iommu.passthrough=1

DPDK测试实例的编译运行

运行实例前置条件

配置系统巨页HugePages


#分配巨页1024*2M=2G
$ echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
#该分配方法也可行sysctl -w vm.nr_hugepages=2048
#查看大页分配数目
$ cat /proc/meminfo| grep Huge
环境变量:运行DPDK测试实例时,一定要设置环境变量RTE_SDK和RTE_TARGET,用于编译以及索引,无论是采用进入目录直接编译,还是采用usertools/dpdk-setup.sh脚本中的测试实例。
```bash
#这里设置RTE_SDK为dpdk根目录路径
$ export RTE_SDK=/root/github/dpdk
#这里设置RTE_TARGET为dpdk构建依赖平台库名称
$ export RTE_TARGET=x86_64-native-linux-gcc
#开启调试
# export EXTRA_CFLAGS="-O0 -g"

DPDK测试实例$RTE_SDK/example/helloworld

测试用例位于DPDK根目录的examples目录下。

$ cd examples/helloworld/
$ make
    CC main.o
    LD helloworld
    INSTALL-APP helloworld
    INSTALL-MAP helloworld.map

$ ls build/app
    helloworld helloworld.map

在此之前,需要满足如下条件:
已经设置好巨页Hugepages;
任意的内核模块已被载入;
根据实例需求,应用需要的对应网络端口已被绑定到相应内核驱动上。
  应用程序会链接DPDK目标环境库——EAL(Environmental Abstraction Layer),它能够提供给所有DPDK应用程序一种通用的功能选项。其中-c/-l是强制的,其他都是可选参数,-l表示内核编号的集合,-n表示每个socket的内存通道数量。读者可参考官方文章http://doc.dpdk.org/guides-20.02/linux_gsg/build_sample_apps.html

cd build
./helloworld -l 0-1 -n 2

DPDK测试实例$RTE_TARGET/app/test

$ cd /root/github/dpdk/usertools
$ ./dpdk-setup.sh
# 加载驱动并已绑定网卡
# 选择[54] Run test application
# 因测试环境2核,输入内核的16进制掩码,二进制是00000011
bitmask: 0x03
Launching app
EAL: Detected 2 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: Probing VFIO support...
EAL: PCI device 0000:02:01.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:02.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:06.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100f net_e1000_em
APP: HPET is not enabled, using TSC as default timer
RTE>>

虚拟机环境中的错误Input/output error处理

EAL: Error reading from file descriptor 19: Input/output error
APP: HPET is not enabled, using TSC as default timer
RTE>>EAL: Error reading from file descriptor 22: Input/output error
如果出现如上问题,是因为虚拟机添加的网卡,dpdk不支持导致的,需要在编译igb_uio驱动代码的时候,修改一行代码,跳过dpdk pci 检查。在dpdk/kernel/linux/igb_uio/igb_uio.c文件中,找到 if (pci_intx_mask_supported(udev->pdev)这行代码(dpdkv20.02),
然后修改为if (pci_intx_mask_supported(udev->pdev)|| 1)。
然后重新编译驱动,并重新加载igb_uio,即可解决该问题。

https://blog.csdn.net/jmilk/category_9977777.html

### 回答1: DPDK(Data Plane Development Kit)是一种高性能数据面开发工具包。深入浅出DPDK是一份详细介绍DPDK的PDF文档,适合初学者了解DPDK的基本概念和使用方法。 该文档从DPDK的介绍开始,介绍了DPDK的发展历史、使用场景和目标。接着详细介绍了DPDK的架构,包括主要组件和数据流向。其中详细介绍了包管理的基本原理和流程、缓存池的管理方式、内存对齐和地址映射等内容。 文档还介绍了如何使用DPDK,包括DPDK编译和安装、如何使用DPDK进行虚拟网络功能(VNF)处理,以及如何使用DPDK进行数据包嗅探和过滤等。 此外,该文档还介绍了DPDK的性能优化技巧,包括如何优化包接收和处理、如何使用多核心优化性能和如何配置DPDK与硬件交互。 总体而言,深入浅出DPDK是一份非常有价值的文档,它不仅为初学者提供了详细的DPDK介绍和使用指南,还涵盖了DPDK的高级主题和性能优化技巧,为使用DPDK进行高性能数据面开发的人员提供了重要的参考资料。 ### 回答2: DPDK(Data Plane Development Kit)是一个高性能数据平面开发工具包,它使用用户态技术实现了零拷贝的数据处理和高速的数据包转发。作为一款开源工具,DPDK已经被广泛应用于虚拟化、云计算及网络功能虚拟化等领域。 《深入浅出dpdk》是一份由DPDK社区编写的指南,它的目的是帮助开发人员更好地了解DPDK,并使用DPDK构建高性能网络应用程序。该指南提供了详细的DPDK架构、API接口、应用案例和性能调优等方面的介绍,同时也介绍了其他相关技术,例如硬件加速、 NUMA架构、 数据库加速、分布式系统等。 《深入浅出dpdk》PDF版本可以从DPDK社区网站上自由下载,它包含了大量易懂的图表和代码实例,让开发人员更容易理解DPDK的概念和原理。对于想要在高性能数据平面开发方面取得突破的开发人员来说,这份指南是不可或缺的学习资料。 需要注意的是,《深入浅出dpdk》不仅是一份教材,更是一份指导开发人员如何使用DPDK进行数据平面开发的实际指南。开发人员在阅读本指南的同时,也需要具备一定的网络编程基础和C语言编程能力。同时,开发过程中还需要注意DPDK版本的兼容性和网络设备的支持情况。 ### 回答3: DPDK(Data Plane Development Kit)是一种高性能数据面开发工具包,它可以帮助开发人员快速地实现高性能网络应用程序。本篇文章解析的Deep Dive into DPDK的PDF文件是一份帮助初学者深入了解DPDK的指南,其中详细地介绍了DPDK的各种重要概念、特性和使用方法。 首先,这份PDF文件详细介绍了DPDK的架构和工作原理。DPDK采用轮询机制减少了对内核的依赖,从而显著提高了网络数据处理的性能。此外,本文还介绍了DPDK中各种组件的作用和功能,例如EAL(Environment Abstraction Layer)、Mempool、Ring等。这些组件都是DPDK中重要的工具,它们可以帮助开发人员更好地构建高性能应用程序。 其次,本文还介绍了如何使用DPDK来构建网络应用程序。首先,开发人员需要安装DPDK,并正确配置相应环境变量。其次,本文还介绍了如何使用DPDK的API来实现数据包的发送和接收。这些API提供了高效的数据传输方式和内存管理方式,开发人员可以根据自己的需求进行自定义。 此外,本文还介绍了DPDK的一些高级功能,例如NUMA支持、内存优化等。这些功能可以帮助开发人员更好地控制和管理系统资源,从而确保系统的高性能和稳定性。 总之,本文是一份非常实用的DPDK指南,其中介绍了DPDK的各种重要概念、特性和使用方法。初学者可以通过阅读这份文件,快速掌握DPDK的核心知识,为构建高性能应用程序打下牢固的基础。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值