UDPDK是基于DPDK的最小UDP栈,用于服务器之间的快速点对点通信。
它完全在用户空间中运行,因此您可以快速移动数据包,而无需经过繁琐的内核堆栈。
此外,由于其类似posix的API,将现有应用程序移植到UDPDK非常容易!
UDPDK是什么:
确认了一下万兆网卡的型号为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支持的网卡型号
跟着这个走就可以了,就是文档说的比较简略
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版本比较老旧,新版本有更新解决这些问题
加载 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
选择
[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,开启虚拟化
结果还是不行,无法绑定,尝试了很多方法也不行
然后在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
===================================
上面的都是在安装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插件快速发布