UDPDK安装

UDPDK介绍

UDPDK是基于DPDK的最小UDP栈,用于服务器之间的快速点对点通信。

它完全在用户空间中运行,因此您可以快速移动数据包,而无需经过繁琐的内核堆栈。

此外,由于其类似posix的API,将现有应用程序移植到UDPDK非常容易!

UDPDK是什么:

  • 一个传输级网络堆栈
  • 在DPDK之上的类似posix的UDP套接字实现
  • 一个低延迟数据包交换的框架

接收机器网卡详细信息

确认了一下万兆网卡的型号为E810-C,速率为25Gb/s

 *-network:0 //万兆网卡,数据网
       description: Ethernet interface
       product: Ethernet Controller E810-C for QSFP
       vendor: Intel Corporation
       physical id: 0
       bus info: pci@0000:03:00.0
       logical name: enp3s0f0
       version: 02
       serial: 6c:b3:11:21:c5:36
       capacity: 25Gbit/s
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi msix pciexpress vpd bus_master cap_list rom ethernet physical 10000bt-fd 25000bt-fd autonegotiation
       configuration: autonegotiation=off broadcast=yes driver=ice driverversion=5.15.0-1084-realtime firmware=3.20 0x8000d84c 1.3146.0 latency=0 link=no multicast=yes
       resources: irq:16 memory:ac000000-adffffff memory:b2000000-b200ffff memory:ab300000-ab3fffff memory:b0000000-b0ffffff memory:b2020000-b221ffff
  *-network:1
       description: Ethernet interface
       product: Ethernet Controller E810-C for QSFP
       vendor: Intel Corporation
       physical id: 0.1
       bus info: pci@0000:03:00.1
       logical name: enp3s0f1
       version: 02
       serial: 6c:b3:11:21:c5:37
       capacity: 25Gbit/s
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi msix pciexpress vpd bus_master cap_list rom ethernet physical 10000bt-fd 25000bt-fd autonegotiation
       configuration: autonegotiation=off broadcast=yes driver=ice driverversion=5.15.0-1084-realtime firmware=3.20 0x8000d84c 1.3146.0 latency=0 link=no multicast=yes
       resources: irq:16 memory:ae000000-afffffff memory:b2010000-b201ffff memory:ab200000-ab2fffff memory:b1000000-b1ffffff memory:b2220000-b241ffff
  *-network //千兆网卡,控制网
       description: Ethernet interface
       product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
       vendor: Realtek Semiconductor Co., Ltd.
       physical id: 0
       bus info: pci@0000:07:00.0
       logical name: enp7s0
       version: 15
       serial: 4c:ed:fb:ca:f2:2c
       size: 1Gbit/s
       capacity: 1Gbit/s
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress msix bus_master cap_list ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=r8169 driverversion=5.15.0-1084-realtime duplex=full firmware=rtl8168h-2_0.0.2 02/26/15 ip=211.67.26.58 latency=0 link=yes multicast=yes port=twisted pair speed=1Gbit/s
       resources: irq:19 ioport:3000(size=256) memory:ab404000-ab404fff memory:ab400000-ab403fff

查询DPDK支持的网卡型号 list

安装流程

跟着这个走就可以了,就是文档说的比较简略

https://github.com/leoll2/UDPDK?tab=readme-ov-file

更具体的看下面内容

提供了命令行安装工具

cd dpdk/usertools
./dpdk-setup.sh

编译

首先是编译,根据系统架构选择,查看系统架构可以输入命令arch,这里的结果是

x86_64

所以编译选择

[38] x86_64-native-linuxapp-gcc

这里给我整吐了,有好几个地方报错,这些文件都是别人写好的库文件,按道理不会报错。

结果是因为使用了未初始化的变量 r_bitmap 等等,还有缩进也会导致错误,define导致的重定义问题,导致编译器警告。

由于启用了 -Werror=maybe-uninitialized 编译选项,所有可能未初始化使用的警告都被当作错误处理。

然后我一个一个打开源文件去修改然后重新编译,一共有十几个要改的地方吧,折腾了好久。

后来网上搜了一下说是这个dpdk版本比较老旧,新版本有更新解决这些问题

加载VIFO驱动

加载 VFIO 驱动模块。VFIO 提供了安全的设备直通功能,是 DPDK 推荐使用的驱动

VFIO代表的是“Virtual Function I/O”, 在DPDK环境中,VFIO可以用来绑定物理网卡到DPDK应用程序

配置大页内存

传统上,操作系统将物理内存划分为固定大小的小页面(通常为4KB),并通过页表来管理虚拟内存与物理内存之间的映射关系。然而,随着系统中可用物理内存的增加,这种小页面的管理模式可能导致一些性能问题,如TLB(Translation Lookaside Buffer)未命中率增加、内存碎片增多以及内存管理开销增大等。 大页内存使用比默认小页面(如4KB)更大的内存页面大小(例如2MB甚至1GB)

大页内存减少了虚拟地址到物理地址转换所需的页表项数量,这直接降低了Translation Lookaside Buffer (TLB) 的未命中率。TLB是CPU中的一个缓存,用于存储最近使用的虚拟地址到物理地址的映射。使用更大的页面可以覆盖更多的内存区域,因此减少了需要查询主内存中的页表次数,从而提高了内存访问速度。对于网络数据包处理这种对延迟敏感的应用来说尤为重要。

首先要确定电脑是单NUMA节点还是多NUMA节点,通常桌面系统(个人电脑)都是单NUMA节点

输入命令

lscpu

看到结果说明确实是单NUMA节点

NUMA:
  NUMA node(s):           1
  NUMA node0 CPU(s):      0-11

然后选择

[48] Setup hugepage mappings for non-NUMA systems

然后根据这个信息输入要配置的页数,一个页大小为2MB,输入1024就配置2GB的大页内存空间

Input the number of 2048kB hugepages
Example: to have 128MB of hugepages available in a 2MB huge page system,
enter '64' to reserve 64 * 2MB pages
Number of pages:

GRUB(GRand Unified Bootloader)是一个多重引导规范的实现,它允许用户在计算机启动时选择加载哪个操作系统。GRUB是Linux系统中最常用的引导加载程序之一,它可以让你从多个操作系统中选择一个来启动,并且支持各种启动选项和配置。

在DPDK安装过程中,GRUB的重要性体现在配置大页内存(Huge Pages)以优化性能方面。为了确保在系统启动时就能预留出足够的大页内存供DPDK使用,你需要编辑GRUB的配置文件(通常是/etc/default/grub),并添加或修改内核启动参数来指定大页内存的大小和数量。

需要设置

GRUB_CMDLINE_LINUX="default_hugepagesz=2MB hugepagesz=2MB nr_hugepages=1024 isolcpus=0-7"

然后再命令行

sudo update-grub

然后重启一下电脑才能更新配置

然后输入命令查看大页配置情况

grep Huge /proc/meminfo
HugePages_Total:    1024
HugePages_Free:     1024
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:         2097152 kB

网卡绑定VIFO驱动

选择

[52] Bind Ethernet device to VFIO module

然后输入要绑定网卡的PCI地址,这里把电脑上网口都给列出来了,万兆网卡有两个网口,千兆网卡有一个网口,都有各自的PCI地址,这里选择输入0000:03:00.0

Network devices using kernel driver
===================================
0000:03:00.0 'Ethernet Controller E810-C for QSFP 1592' if=enp3s0f0 drv=ice unused=vfio-pci
0000:03:00.1 'Ethernet Controller E810-C for QSFP 1592' if=enp3s0f1 drv=ice unused=vfio-pci
0000:07:00.0 'RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller 8168' if=enp7s0 drv=r8169 unused=vfio-pci *Active*

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

Enter PCI address of device to bind to VFIO driver:

结果绑定失败了,应该是这个vfio-pci的问题

Error: bind failed for 0000:03:00.0 - Cannot bind to driver vfio-pci
Error: unbind failed for 0000:03:00.0 - Cannot open /sys/bus/pci/drivers//unbind

根据搜索,首先重启电脑进入BIOS,开启虚拟化 vt

结果还是不行,无法绑定,尝试了很多方法也不行

然后在stackoverflow上找到解决方法,在root模式下输入

echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode

然后就可以绑定网卡到vfio-pci了

绑定好后是这样的,可以看到万兆网卡的两个端口现在都绑定到vfio-pci驱动上

root@ddaq-System-Product-Name:/home/ddaq/UDPDK/deps/dpdk/usertools# sudo python3 dpdk-devbind.py --status

Network devices using DPDK-compatible driver
============================================
0000:03:00.0 'Ethernet Controller E810-C for QSFP 1592' drv=vfio-pci unused=ice
0000:03:00.1 'Ethernet Controller E810-C for QSFP 1592' drv=vfio-pci unused=ice

Network devices using kernel driver
===================================
0000:07:00.0 'RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller 8168' if=enp7s0 drv=r8169 unused=vfio-pci *Active*

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

安装UDPDK

上面的都是在安装DPDK,下面是安装UDPDK,非常简单,就是编译一些文件而已

cd udpdk
make
sudo make install

如果有报错说未定义环境变量RTE_TARGET 就输入这个命令

export RTE_TARGET=x86_64-native-linuxapp-gcc

安装好后可以看到就提供了一系列头文件和API函数了

root@ddaq-System-Product-Name:/home/ddaq/UDPDK/udpdk# make install
rm -f /usr/local/lib/libudpdk.a.1.0
rm -f /usr/local/lib/libudpdk.a
rm -f /usr/local/include/udpdk_*.h
rm -f /usr/local/include/list/udpdk_*.h
rm -f /usr/local/include/shmalloc/udpdk_*.h
cp -f libudpdk.a /usr/local/lib/libudpdk.a.1.0
ln -sf /usr/local/lib/libudpdk.a.1.0 /usr/local/lib/libudpdk.a
cp -f udpdk_*.h /usr/local/include/
cp -f list/udpdk_*.h /usr/local/include/
cp -f shmalloc/udpdk_*.h /usr/local/include/
root@ddaq-System-Product-Name:/home/ddaq/UDPDK/udpdk# ls /usr/local/include
udpdk_api.h   udpdk_bind_table.h  udpdk_dump.h  udpdk_list_init.h  udpdk_poller.h    udpdk_sync.h
udpdk_args.h  udpdk_constants.h   udpdk_list.h  udpdk_monitor.h    udpdk_shmalloc.h  udpdk_types.h

本文章使用limfx的vscode插件快速发布