DPDK
- 系统: ubuntu22.4
- CPU:普通I5 / Intel至强CPU 2x64
- 内存:8x32G 3200HZ
- 网卡: MCX556A-ECAT 两个网口
测试网卡
将网卡插在电脑上,第一步肯定就是想测试一下是否可以ping通,顺便测试一下硬件是否可用
硬件:
- MCX556A-ECAT
- 100G光纤模块和100G专用的光纤
将网卡中的两个网络接口使用光模块和光纤直连
PCI报错导致网卡不工作
这个报错信息如果有再追加pcie_aspm=off参数进行关闭,因为不知道如果不报错的话关闭了会不会引起其他的错误。
PCIe Bus Error: severity=Corrected, type=Physical Layer, 报错以后整个网卡就挂掉了无法使用,重启网卡都不行,只能重启电脑
查询相关资料后在grub中添加 pcie_aspm=off, 这个属性的意思好像是将PCIE的低功率关掉,以下是ChatGPT3.5的回答
PCIE_ASPM=off是Linux内核参数,用于禁用PCI Express(Peripheral Component Interconnect Express)总线的Active State Power Management(ASPM)。
ASPM是一种节能技术,允许PCIe设备在不活动时进入低功耗状态,以减少功耗。然而,在某些情况下,ASPM可能会导致系统不稳定或设备无法正常工作。
设置PCIE_ASPM=off可以禁用ASPM,强制PCIe设备保持高功耗状态,可能会解决一些与ASPM相关的问题。但是,这也可能会增加系统的功耗。
通常情况下,PCIE_ASPM=off用于解决以下问题:
1、PCIe设备无法正常工作或不稳定
2、系统崩溃或蓝屏
3、设备无法从睡眠状态中唤醒
需要注意的是,禁用ASPM可能会增加系统的功耗,从而影响系统的续航时间或增加heat生成。因此,仅当必要时才应该禁用ASPM。
$ sudo vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pcie_aspm=off"
$ sudo update-grub
$ sudo reboot
配置静态路由
经过实验被DPDK接管的网卡应该是不需要设置IP地址的,此章节除了配置IP时添加 optional: true让系统不在启动界面长时间等待,其他操作全部作废
如果配置了IP地址的话,抓包时一直发送arp报文。而且除了麦洛斯Mellanox 网卡其它网卡在被DPDK接管以后系统层面也看不到了,所以根本无需配置。
配置静态IP
$ sudo vim /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
ethernets:
ens42f0:
dhcp4: false
addresses: [192.168.1.4/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [8.8.8.8,8.8.8.4]
# 以下是添加的MCX556A-ECAT网卡的名字以及静态IP
enp87s0f0np0:
dhcp4: false
#addresses: [192.168.2.12/24]
optional: true
enp87s0f1np1:
dhcp4: false
#addresses: [192.168.2.13/24]
# optional: true 可以处理多网卡时没有配置的网卡不会在启动界面长时间等待
optional: true
version: 2
renderer: networkd
$ vim /etc/iproute2/rt_tables
#增加内容:
11 net_1
10 net_0
配置静态路由
$ ip route add 192.168.2.0/24 dev enp1s0f0np0 src 192.168.2.12 table net_0
$ ip route add default dev enp1s0f0np0 table net_0
$ ip rule add from 192.168.2.12 table net_0
$ ip route add 192.168.2.0/24 dev enp1s0f1np1 src 192.168.2.13 table net_1
$ ip route add default dev enp1s0f1np1 table net_1
$ ip rule add from 192.168.2.13 table net_1
$ ip route flush cache
第1步:
把路由表序号(10、11)和路由表名字(net_0、net_1)添加到/etc/iproute2/rt_tables中
第2步:
(1)ip route add 192.168.2.0/24 dev eth0 src 192.168.2.10 table net_0
从192.168.2.10发送到192.168.2.0/24网段的数据从eth0发出,把该路由项添加到路由表net_0中
(2)ip route add default dev eth0 table net_0
在路由表中添加默认路由,默认路由从eth0进出
(3)ip rule add from 192.168.2.10 table net_0
添加路由策略,来自192.168.2.10的路由要求使用net_0
(4) ip route flush cache
把新添加的路由策略和路由表刷新到缓存中,即时生效
按照以上方式配置好以后可以通过指定IP ping,但是指定网卡名字ping却ping不通不知道为什么?
# 这种方式可以ping通
$ ping -I 192.168.2.12 192.168.2.13
# 指定网卡的方式则ping不通
$ ping -I enp1s0f0np0 192.168.2.13
而且后来发现,不用配置以上的操作,只要配置好了IP,指定IP的方式也可以ping通,无了个语了。
安装mft工具
此工具可以设置MCX556A网卡的许多功能
在上面的网址中选择版本和相应的系统后下载deb版本或者使用以下命令进行下载,但是链接地址可能实效
$ wget https://www.mellanox.com/downloads/MFT/mft-4.26.1-6-x86_64-deb.tgz
$ tar -xvf mft-4.26.1-6-x86_64-deb.tgz
$ mv mft-4.26.1-6-x86_64-deb mft
$ cd mft
$ sudo ./install.sh
-E- There are missing packages that are required for installation of MFT.
-I- You can install missing packages using: apt-get install dkms
$ sudo apt-get install dkms
# 安装依赖包以后再次进行安装
$ sudo ./install.sh
$ sudo mst start
# 启动以后会生成/dev/mst/mt4119_pciconf0符号设备, 有可能名字不一样
$ sudo flint -d /dev/mst/mt4119_pciconf0
Image type: FS4
FW Version: 16.26.4012
FW Release Date: 27.6.2024
Product Version: 16.26.4012
Rom Info: type=UEFI version=14.29.15 cpu=AMD64
type=PXE version=3.6.902 cpu=AMD64
Description: UID GuidsNumber
Base GUID: 0c42a10300ac0b66 8
Base MAC: 0c42a1ac0b66 8
Image VSD: N/A
Device VSD: N/A
PSID: MT_0000000008
Security Attributes: N/A
安装MCX556A网卡驱动
运行demsg后, 有NUMA报错信息
[ 34.025278] Fail to get numa node for CPU:127 bus:1 dev:30 fn:1
网络上的解决办法: BIOS -> Memory Settings -> Node Interleaving: Enabled
这个报错信息没有解决,以上操作也没有在BIOS中找到相应的设置,没有感觉到有什么影响所以作罢。
通过命令可以看到NUMA有两个节点,CPU核心在不同的NUMA节点上
$ lscpu | grep -i numa
NUMA node(s): 2
NUMA node0 CPU(s): 0-31,64-95
NUMA node1 CPU(s): 32-63,96-127
ubuntu22.4系统自带了网卡驱动,还需要安装驱动?
因为原系统自带的驱动不支持dpdk,需要重新安装驱动以支持dpdk,因为没有提前重新安装驱动,导致后面DPDK识别不到网卡,一直以为是dpdk配置的问题,折腾了快3天,真折磨。
此网卡对应的就是NVIDIA® ConnectX®-5 100G MCX556A-ECAT (2x100G)的驱动
可以在 nics 找到NVIDIA选项卡,点进去以后可以看到是支持这个网卡使用DPDK技术的
在使用DPDK之前需要先安装相应的网卡驱动,使用NVIDIA官方提供的MLNX_OFED方式安装
在网卡驱动链接中选择相应版本和相应的linux系统下载,我是Ubuntu22.4 就选择ubuntu22.4 x86平台然后下载即可
安装驱动
报错
Removing old packages…
Error: One or more packages depends on MLNX_OFED_LINUX.
Those packages should be removed before uninstalling MLNX_OFED_LINUX:
libcaf-openmpi-3 openmpi-common libopenmpi3 libucx0 libopenmpi-dev libcoarrays-openmpi-dev libfabric1 openmpi-bin
To force uninstallation use ‘–force’ flag.
大概意思让我把这些软件卸载后再安装驱动,提示使用参数–force强制安装,不知道这些会不会被卸载之后就不再安装,可以在安装网卡驱动后再手动重新安装一遍。
下载后运行
$ tar -xvf MLNX_OFED_LINUX-23.10-2.1.3.1-ubuntu20.04-x86_64.tgz
$ cd MLNX_OFED_LINUX-23.10-2.1.3.1-ubuntu20.04-x86_64/
# --add-kernel-support参数会根据当前内核重新编译驱动 如果有kernel报错再使用这个参数
# --force 参数强制卸载旧的软件
$ sudo ./mlnxofedinstall --dpdk --force
.
.
.
Installation passed successfully
To load the new driver, run:
/etc/init.d/openibd restart
$ sudo /etc/init.d/openibd restart
Unloading HCA driver: [ OK ]
Loading HCA driver and Access Layer: [ OK ]
安装好以后确认相关依赖都安装成功
$ pkg-config --modversion libibverbs
1.14.47.0
$ pkg-config --modversion libmlx5
1.24.47.0
$ lsmod | egrep "^mlx5_core|^mlx5_ib|^ib_uverbs"
mlx5_ib 3211264 0
ib_uverbs 1097728 1 mlx5_ib
mlx5_core 10534912 1 mlx5_ib
在安装完驱动后,可通过 ibv_devinfo 来查看网卡当前模式,运行DPDK需要网卡在ETH模式
$ ibv_devinfo
hca_id: mlx5_0
transport: InfiniBand (0)
fw_ver: 16.26.4012
node_guid: b859:9f03:00b4:41bc
sys_image_guid: b859:9f03:00b4:41bc
vendor_id: 0x02c9
vendor_part_id: 4119
hw_ver: 0x0
board_id: MT_0000000008
phys_port_cnt: 1
port: 1
state: PORT_ACTIVE (4)
max_mtu: 4096 (5)
active_mtu: 1024 (3)
sm_lid: 0
port_lid: 0
port_lmc: 0x00
link_layer: Ethernet
hca_id: mlx5_1
transport: InfiniBand (0)
fw_ver: 16.26.4012
node_guid: b859:9f03:00b4:41bd
sys_image_guid: b859:9f03:00b4:41bc
vendor_id: 0x02c9
vendor_part_id: 4119
hw_ver: 0x0
board_id: MT_0000000008
phys_port_cnt: 1
port: 1
state: PORT_ACTIVE (4)
max_mtu: 4096 (5)
active_mtu: 1024 (3)
sm_lid: 0
port_lid: 0
port_lmc: 0x00
link_layer: Ethernet
state: PORT_ACTIVE (4)说明网线插好了
state: PORT_DOWN (1), 说明线没插好.
link_layer: InfiniBand 说明网卡运行在 IB 模式
link_layer: Ethernet 说明网卡运行在 Eth 模式
确保启动mft工具以后使用以下命令可以查看当前网卡的类型为ETH
# 启动mft工具
$ sudo mst start
$ sudo mlxconfig -d /dev/mst/mt4119_pciconf0 query | grep LINK_TYPE
LINK_TYPE_P1 ETH(2)
LINK_TYPE_P2 ETH(2)
网卡类型有以下三种:
link type values are:
- 1 Infiniband
- 2 Ethernet
- 3 VPI (auto-sense)
可通过mlx命令进行改变
$ sudo mlxconfig -d /dev/mst/mt4119_pciconf0 set LINK_TYPE_P1/2=1/2/3
如果改变了网卡的类型必须使用以下命令进行重置
$ sudo mlxfwreset -d /dev/mst/mt4119_pciconf0 reset
编译DPDK
运行DPDK程序的系统的要求
Kernel version >= 4.14,使用 uname -r 检查内核版本
glibc >= 2.7 ,使用 ldd --version 检查版本
系统环境安装
$ sudo apt install gcc
$ sudo apt install python3-pip build-essential
$ sudo pip3 install meson ninja
$ sudo apt install python3-pyelftools
$ sudo apt install libnuma-dev
$ sudo apt install libpcap-dev
下载DPDK源码并编译
$ wget http://fast.dpdk.org/rel/dpdk-23.11.1.tar.xz
$ tar -xJf dpdk-23.11.1.tar.xz
$ cd dpdk-stable-23.11.1
# 默认安装 默认安装路径是/usr/local/
meson setup -Dexamples=all build
# dpdk安装目录自己创建
$ meson setup -Dprefix=[dpdk安装目录] build
$ cd build
# 编译
$ ninja -j4
# 安装
$ meson install
# ldconfig 命令好像只能在默认安装目录时使用,如果是指定安装目录的话好像就不可以用这个命令来创建共享目录缓存了,可以通过使用以下方式将.pc文件设置到系统路径中
$ sudo ldconfig
如果自定义了安装路径,为了在系统范围内使用dpdk,需要将DPDK的相关依赖库和头文件等等假如系统路径,默认安装的话不需要设置
当安装后,DPDK提供了一个pkg-config文件libdpdk.pc为应用程序查询依赖库以及头文件等等的路径
将pk_config设置到系统路径中,编译时通过路径下的.pc文件查找动态库以及头文件等等,这个变量是临时的,关闭了命令行窗口就会失效
# 因为之前安装的dpdk环境不在系统范围内(自己指定目录安装的),所以在编译之前需要先把dpdk的环境配置到环境变量中
$ export PKG_CONFIG_PATH=[dpdk安装目录]/lib/x86_64-linux-gnu/pkgconfig
# 上述命令只在当前窗口中生效,关闭当前窗口后即实效,如果想要在当前用户下永久生效,可以在.bashrc文件中添加上面的命令
$ sudo vim ~/.bashrc
export PKG_CONFIG_PATH=[dpdk安装目录]/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH
# 运行source命令生效配置
$ source ~/.bashrc
$ export LD_LIBRARY_PATH=[dpdk安装目录]/lib/x86_64-linux-gnu/
# 同样将dpdk的依赖库目录在系统范围内生效可以修改ld.so.conf文件
$ sudo vim /etc/ld.so.conf
[dpdk安装目录]/lib/x86_64-linux-gnu
# 查看添加的目录是否生效
$ sudo ld-config -v
如果想要卸载dpdk可以使用以下命令
$ cd /xxx/build
$ sudo ninja uninstall
dpdk程序运行环境设置
DPDK程序运行必须设置HUGE
DPDK官方建议,64位的应用应配置1GB hugepages。
这种配置方式的优点是可以在系统开机时即配置预留好hugepages,避免系统运行起来后产生内存碎片;另外,对于较大的例如1G pages,是不支持在系统运行起来后配置的,只能通过kernel cmdline的方式进行配置。
# 查看宿主机中HugePage的大小
$ cat /proc/meminfo | grep -i HugePages
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 4096 kB
HugePages_Total: Hugepage的页面数量
HugePages_Free: 剩余的页面数量
HugePages_Rsvd: 被分配预留但是还没有使用的page数目
HugePages_Surp:HugePages_Total减去/proc/sys/vm/nr_hugepages中的值
Hugepagesize: hugepage的大小
编辑grub文件设置huge,改变GRUB_CMDLINE_LINUX的属性值,hugepages的个数如果在NUMA多节点中会被平均的分配给每一个节点,比如我的设备NUMA节点是2,那么每个节点将会得到8个。
$ sudo vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="default_hugepagesz=1G hugepagesz=1G hugepages=16 quiet splash pcie_aspm=off"
# 修改并保存后运行以下命令,重启生效
$ sudo update-grub
为DPDK预留huge以后需要挂载使用
$ sudo mkdir /mnt/huge
$ sudo mount -t hugetlbfs pagesize=1GB /mnt/huge
# 查看挂载
$ mount | grep hugetlbfs
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=1024M)
nodev on /mnt/huge type hugetlbfs (rw,relatime,pagesize=1024M)
# 修改fstab文件使其开机自动挂载
$ sudo vim /etc/fstab
nodev /mnt/huge hugetlbfs pagesize=1GB 0 0
$ sudo chmod 777 /mnt/huge
# 重启设备生效
$ reboot
上述命令中查看挂载时显示了两个,第一个显示挂载到/dev/hugepages下,那也就是说系统默认为hugepage挂载了1G的目录了,经过查找找到一个dev-hugepages.mount服务,在系统启动时进行了挂载
$ systemctl status dev-hugepages
dev-hugepages.mount - Huge Pages File System
Loaded: loaded (/proc/self/mountinfo; static)
Active: active (mounted) since Wed 2024-09-18 00:46:54 UTC; 1 day 5h ago
Where: /dev/hugepages
What: hugetlbfs
Docs: https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
Tasks: 0 (limit: 269602)
Memory: 56.0K
CPU: 1ms
CGroup: /dev-hugepages.mount
Notice: journal has been rotated since unit was started, output may be incomplete.
# 内容如下
$ cat /lib/systemd/system/dev-hugepages.mount
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Huge Pages File System
Documentation=https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/sys/kernel/mm/hugepages
ConditionCapability=CAP_SYS_ADMIN
ConditionVirtualization=!private-users
[Mount]
What=hugetlbfs
Where=/dev/hugepages
Type=hugetlbfs
那是不是可以不用再挂载了呢?
- 关于VFIO-PCI驱动
官方建议使用VFIO-PCI,Linux内核从3.6.0版本之后就一直包含VFIO模块,但是MCX5网卡不需要使用VFIO-PCI驱动,自家的网卡驱动本身支持了DPDK技术,所以不需要加载其他的驱动
$ sudo modprobe vfio-pci
- IOMMU技术
IOMMU技术需要硬件支持VT-d技术,如果不需要使用SR-IOV和MCX5网卡的VF功能,那么不需要开启IOMMU,也就不用在grub文件中添加 intel_iommu=on iommu=pt;暂时没有搞明白DPDK使用SR-IOV好还是不使用好。
$ sudo vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="default_hugepagesz=1G hugepagesz=1G hugepages=4 intel_iommu=on iommu=pt quiet pcie_aspm=off"
$ sudo update-grub
$ sudo reboot
重启后查看IOMMU是否开启, 如果显示IOMMU enabled代表开启了
$ dmesg | grep -e DMAR -e IOMMU
DMAR: IOMMU enabled
- 隔离CPU
隔离CPU的编号,尽量选择网卡所在的插槽上的CPU核心编号,使用以下命令查看PCI设备在NUMA哪个节点上
$ lspci | grep Mellanox
57:00.0 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
57:00.1 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
$ sudo lspci -vvvs 57:00.0 | grep NUMA
NUMA node: 0
$ sudo lspci -vvvs 57:00.1 | grep NUMA
NUMA node: 0
两个设备都在NUMA节点0上,也就是CPU0,那么隔离的CPU编号应该是CPU0的核心编号,以下命令查看CPU0有哪些编号
$ lscpu | grep -i numa
NUMA node(s): 2
NUMA node0 CPU(s): 0-31,64-95
NUMA node1 CPU(s): 32-63,96-127
可以选择CPU0上的64-95将其隔离
$ sudo vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="default_hugepagesz=1G hugepagesz=1G hugepages=16 pcie_aspm=off isolcpus=64-95"
$ sudo update-grub
# 重启设备生效
- DPDK调优
这这篇文章中,建议在BIOS中关闭VT-D技术
更多设置可以参考以下链接
编译官方程序helloworld
Before running the application make sure:
1、Hugepages setup is done.
2、Any kernel driver being used is loaded.
3、In case needed, ports being used by the application should be bound to the corresponding kernel driver.
refer to linux-drivers for more details.
Intel网卡需要网卡绑定到DPDK环境中(Mellanox网卡不需要绑定)
$ dpdk-devbind.py --bind=vfio-pci [网卡名字/pci addr]
查看网卡状态
$ dpdk-devbind.py --status
etwork devices using kernel driver
===================================
0000:00:14.3 'Device 7af0' if=wlp0s20f3 drv=iwlwifi unused=vfio-pci
0000:00:1f.6 'Ethernet Connection (17) I219-LM 1a1c' if=enp0s31f6 drv=e1000e unused=vfio-pci *Active*
0000:01:00.0 'MT27800 Family [ConnectX-5] 1017' if=enp1s0f0np0 drv=mlx5_core unused=vfio-pci *Active*
0000:01:00.1 'MT27800 Family [ConnectX-5] 1017' if=enp1s0f1np1 drv=mlx5_core unused=vfio-pci *Active*
网卡此时使用的mlx5_core官方驱动
编译helloworld
$ cd [dpdk安装目录]/share/examples/helloworld
$ make
$ sudo ./build/helloworld
EAL: Detected CPU lcores: 12
EAL: Detected NUMA nodes: 1
EAL: Detected shared linkage of DPDK
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'VA'
EAL: VFIO support initialized
EAL: Probe PCI driver: mlx5_pci (15b3:1017) device: 0000:01:00.0 (socket -1)
mlx5_net: No available register for sampler.
EAL: Probe PCI driver: mlx5_pci (15b3:1017) device: 0000:01:00.1 (socket -1)
mlx5_net: No available register for sampler.
TELEMETRY: No legacy callbacks, legacy socket not created
hello from core 1
hello from core 2
hello from core 3
hello from core 4
hello from core 5
hello from core 6
hello from core 7
hello from core 8
hello from core 9
hello from core 10
hello from core 11
hello from core 0
如果一切设置正确,那么将会看到hello在cpu的每一个核心上被运行
(socket -1) 是因为 /sys/class/net/enp1s0f0np0/device/numa_node 文件中的值为-1
意思是没有绑定到numa节点中,可以通过 lscpu 命令查看节点数,节点的值从0开始,可以通过以下命令绑定到某个节点上
$ lscpu | grep NUMA
NUMA 节点: 1
NUMA 节点0 CPU: 0-11
$ sudo cat /sys/class/net/enp1s0f0np0/device/numa_node
-1
$ sudo chmod 666 /sys/class/net/enp1s0f0np0/device/numa_node
$ sudo echo > 0 /sys/class/net/enp1s0f0np0/device/numa_node
$ sudo echo > 0 /sys/class/net/enp1s0f1np1/device/numa_node
设置完成以后再运行 socket 就不会是-1了, 但是有什么影响暂时没有看出来,这种设置方式每次重启后都需要手动设置,不设置好像也没什么影响,在支持numa的机器上就不会是-1了。
非root用户执行
非root用户运行dpdk程序时,需要将大页内存挂载点权限改变为可写,例如挂载点为/mnt/huge
$ sudo chmod 777 /mnt/huge
$ sudo setcap cap_net_raw,cap_dac_override=eip [要运行的程序]
$ ./[要运行的程序] --huge-dir /mnt/huge
DPDK多进程
编译官方示例skeleton,这是一个基本的转发示例,在编译后我想同时运行两个程序,但是第二次报错显示某个文件正在被其它进程使用
EAL: Detected CPU lcores: 128
EAL: Detected NUMA nodes: 2
EAL: Detected shared linkage of DPDK
EAL: Cannot create lock on '/var/run/dpdk/rte/config'. Is another primary process running?
EAL: FATAL: Cannot init config
EAL: Cannot init config
EAL: Error - exiting with code: 1
Cause: Error with EAL initialization
经过多发查证,使用 --file-prefix 参数可以指定要运行的程序所使用的文件目录, 如果不指定,则使用默认目录下的 /var/run/dpdk/rte/config,指定则会使用 /var/run/dpdk/[指定的目录名称]/config
$ cd [dpdk目录]/examples/skeleton
$ make
$ ./build/basicfwd -l 1
$ ./build/basicfwd -l 2 --file-prefix test
# 运行后就可以在/var/run/dpdk/目录下发现有两个目录,一个是默认创建的,一个是指定名称创建的
$ ls /var/run/dpdk -l
drwx------ 2 root root 220 Sep 19 06:47 rte
drwx------ 2 root root 220 Sep 19 06:49 test
通过上述操作就可以同时运行两个DPDK程序了
性能调优
关闭mlx5网卡的rx tx模块
# 查看网卡是否关闭
$ sudo ethtool -a enp1s0f0np0
$ sudo ethtool -A enp1s0f0np0 rx off tx off
$ sudo ethtool -A enp1s0f1np1 rx off tx off
隔离CPU
$ sudo vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=1-7"
以下是官方建议的优化方式,但是没有明白是干嘛的
On some machines, depends on the machine integrator, it is beneficial to set the PCI max read request parameter to 1K. This can be done in the following way:
To query the read request size use:
$ sudo setpci -s <NIC PCI address> 68.w
If the output is different than 3XXX, set it by:
$ sudo setpci -s <NIC PCI address> 68.w=3XXX
The XXX can be different on different systems. Make sure to configure according to the setpci output.
以下脚本是其它文章的,谨慎使用吧,我是挑着用的
#!/bin/sh
chmod +x /etc/rc.d/rc.local
#1、修改grub,设置cpu隔离和1G大页
#isolcpus=1-7 transparent_hugepage=never default_hugepagesz=1G hugepagesz=1G hugepages=16
#2、关闭numa_balancing和watchdog
echo 0 > /proc/sys/kernel/numa_balancing
echo 0 > /proc/sys/kernel/watchdog
#3、打开文件句柄数调整,默认的4096可能不够
#ulimit -n 65536
#4、CPU打开性能模式
cpupower frequency-set -g performance
#5、网卡中断绑定到系统核上
for irq in `cat /proc/interrupts |egrep -i -e "-(rx|tx|txrx)-" | cut -d: -f1 | sed "s/ //g"`;
do
echo "reset /proc/irq/$irq/smp_affinity"
echo 1 > /proc/irq/$irq/smp_affinity;
done
#6、设置timewait重用
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
#去掉cpu100%的告警
sysctl -w kernel.watchdog=0
#8、关闭其他的服务
systemctl disable irqbalance
systemctl stop irqbalance
systemctl disable firewalld.service
systemctl stop firewalld.service
#9、打开必要服务
#systemctl enable vsftpd
#关闭图形界面
systemctl set-default runlevel3.target
tuned-adm profile latency-performance
TESTPMD测试
-l:指定参与转发的CPU核
-n:指定系统内存通道个数
-w:指定参与DPDK转发的网口的PCIE地址
–rxd/txd:指定转发使用的网口队列深度
–txq/rxq:指定参与转发的网卡队列数
–nb-cores:指定实际参与转发的cpu核数
-i:交互模式启动程序
EAL: Not enough memory available on socket 0! Requested: 8192MB, available: 7168MB
为什么会报错内存不够呢?我这个服务器上有256G的内存啊。为什么呢? 解决:把预留大页的16页改为32页,这样每个NUMA节点将会得到16个预留大页,不知为何每个节点预留8个结果节点1使用了一个导致只剩下7个了。
百兆以太网,一个线速端口的包转发率 = 100,000,000bps / 672bit = 0.148Mpps
千兆以太网,一个线速端口的包转发率 = 1,000,000,000bps / 672bit = 1.488Mpps
万兆以太网,一个线速端口的包转发率 = 10,000,000,000bps / 672bit = 14.88Mpps
$ sudo ethtool -A enp1s0f0np0 rx off tx off
$ sudo ethtool -A enp1s0f1np1 rx off tx off
$ sudo sysctl -w vm.zone_reclaim_mode=0
$ sudo sysctl -w vm.swappiness=0
$ sudo setpci -s 01:00.0 68.w
2930
$ sudo setpci -s 01:00.0 68.w=3930
$ sudo setpci -s 01:00.1 68.w
2930
$ sudo setpci -s 01:00.1 68.w=3930
$ sudo mlxconfig -d /dev/mst/mt4119_pciconf0 set CQE_COMPRESSION=1
$ sudo mlxfwreset -d /dev/mst/mt4119_pciconf0 reset
# sudo dpdk-testpmd -l 1-4 -n 2 -- -i --portmask=0x03 --nb-cores=2
$ sudo dpdk-testpmd -l 1-5 -n 2 -- -i
$ sudo dpdk-testpmd -c 0x06 -n 2 -a 0000:01:00.0 -a 0000:01:00.1 --socket-mem=8192,0 --huge-dir=/mnt/huge -- --port-numa-config=0,0,1,0 --socket-num=0 --burst=64 --txd=1024 --rxd=1024 --mbcache=512 --rxq=1 --txq=1 --nb-cores=1 -i -a --rss-udp --record-core-cycles --record-burst-stats
# --port-numa-config=0,0,1,0: 表示0端口绑定到numa的0 node,1端口也绑定到0 node
# --socket-num=0: 其中 <socket_id> 是要使用的 CPU socket 号(例如,0、1、2 等)。
# --txd=1024在 testpmd 中,--txd 参数用于配置传输描述符(Transmission Descriptor)的数量。
# --burst=64:在 testpmd 中,--burst 参数用于配置数据包 burst 大小。数据包 burst 是指在一个周期内传输的数据包数量。在 DPDK 中,burst 大小决定了每个队列(Queue)中可以传输的数据包数量。传输描述符(TXD)是 DPDK 中的一个数据结构,用于描述要传输的数据包。TXD 包含了数据包的地址、长度、 checksum 等信息。
# --mbcache=512: 在 testpmd 中,mbcache 参数用于配置内存池(Memory Pool)的大小。内存池是 DPDK 中的一个组件,用于管理内存资源。在 testpmd 中,内存池用于存储数据包缓存,以便提高系统的性能和可扩展性。
# 运行以后查看端口统计信息
$ show port stats all
######################## NIC statistics for port 0 ########################
RX-packets: 1158738037 RX-missed: 0 RX-bytes: 147246383735
RX-errors: 0
RX-nombuf: 0
TX-packets: 423132463 TX-errors: 0 TX-bytes: 90973479545
Throughput (since last show)
Rx-pps: 9635150 Rx-bps: 8970721136
Tx-pps: 2475056 Tx-bps: 4257096816
############################################################################
######################## NIC statistics for port 1 ########################
RX-packets: 423133211 RX-missed: 0 RX-bytes: 90973640365
RX-errors: 0
RX-nombuf: 0
TX-packets: 1158740886 TX-errors: 0 TX-bytes: 147246715255
Throughput (since last show)
Rx-pps: 2475194 Rx-bps: 4257334608
Tx-pps: 9635619 Tx-bps: 8971156792
############################################################################
# 停止
$ stop
Telling cores to stop...
Waiting for lcores to finish...
---------------------- Forward statistics for port 0 ----------------------
RX-packets: 1759017356 RX-dropped: 0 RX-total: 1759017356
TX-packets: 577669619 TX-dropped: 0 TX-total: 577669619
RX-bursts : 4236436768 [94% of 0 pkts + 1% of 4 pkts + 0% of 1 pkts + 5% of other]
TX-bursts : 84681459 [0% of 0 pkts + 41% of 4 pkts + 33% of 8 pkts + 26% of other]
----------------------------------------------------------------------------
---------------------- Forward statistics for port 1 ----------------------
RX-packets: 577669619 RX-dropped: 0 RX-total: 577669619
TX-packets: 1759017356 TX-dropped: 0 TX-total: 1759017356
RX-bursts : 4236436768 [98% of 0 pkts + 0% of 4 pkts + 0% of 8 pkts + 2% of other]
TX-bursts : 225444600 [0% of 0 pkts + 20% of 4 pkts + 13% of 1 pkts + 67% of other]
----------------------------------------------------------------------------
+++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++
RX-packets: 2336686975 RX-dropped: 0 RX-total: 2336686975
TX-packets: 2336686975 TX-dropped: 0 TX-total: 2336686975
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CPU cycles/packet=136.00 (busy cycles=317787890462 / total io packets=2336686975) at 2995 MHz Clock
Done.
# 服务器上测试
$ sudo dpdk-testpmd -c 0x06 -n 2 -a 0000:01:00.0 -a 0000:01:00.1 --socket-mem=8192,0 --huge-dir=/mnt/huge -- --port-numa-config=0,0,1,0 --socket-num=0 --burst=64 --txd=1024 --rxd=1024 --mbcache=512 --rxq=1 --txq=1 --nb-cores=1 -i -a --rss-udp --record-core-cycles --record-burst-stats
$ show port stats all
######################## NIC statistics for port 0 ########################
RX-packets: 6987083459 RX-missed: 0 RX-bytes: 419225007540
RX-errors: 0
RX-nombuf: 0
TX-packets: 6986149315 TX-errors: 0 TX-bytes: 419168962740
Throughput (since last show)
Rx-pps: 23100295 Rx-bps: 11088141760
Tx-pps: 23100303 Tx-bps: 11088158496
############################################################################
######################## NIC statistics for port 1 ########################
RX-packets: 6986153091 RX-missed: 0 RX-bytes: 419169185460
RX-errors: 0
RX-nombuf: 0
TX-packets: 6987087171 TX-errors: 0 TX-bytes: 419225230260
Throughput (since last show)
Rx-pps: 23100236 Rx-bps: 11088113640
Tx-pps: 23100236 Tx-bps: 11088113640
############################################################################
$ stop
Telling cores to stop...
Waiting for lcores to finish...
---------------------- Forward statistics for port 0 ----------------------
RX-packets: 7216800515 RX-dropped: 0 RX-total: 7216800515
TX-packets: 7215866435 TX-dropped: 0 TX-total: 7215866435
RX-bursts : 1656875291 [91% of 0 pkts + 5% of 64 pkts + 0% of 3 pkts + 4% of other]
TX-bursts : 139535197 [0% of 0 pkts + 68% of 64 pkts + 6% of 3 pkts + 26% of other]
----------------------------------------------------------------------------
---------------------- Forward statistics for port 1 ----------------------
RX-packets: 7215866435 RX-dropped: 0 RX-total: 7215866435
TX-packets: 7216800515 TX-dropped: 0 TX-total: 7216800515
RX-bursts : 1656875291 [91% of 0 pkts + 5% of 64 pkts + 0% of 3 pkts + 4% of other]
TX-bursts : 138530385 [0% of 0 pkts + 69% of 64 pkts + 6% of 3 pkts + 25% of other]
----------------------------------------------------------------------------
+++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++
RX-packets: 14432666950 RX-dropped: 0 RX-total: 14432666950
TX-packets: 14432666950 TX-dropped: 0 TX-total: 14432666950
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CPU cycles/packet=23.83 (busy cycles=343890597318 / total io packets=14432666950) at 2000 MHz Clock
Done.
# 在性能更好的服务器上运行,单核bps可以达到10G左右,CPU cycles/packet=23.83的值也很低
# 将burst改为512测试
$ sudo dpdk-testpmd -c 0x06 -n 2 -a 0000:01:00.0 -a 0000:01:00.1 --socket-mem=8192,0 --huge-dir=/mnt/huge -- --port-numa-config=0,0,1,0 --socket-num=0 --burst=512 --txd=1024 --rxd=1024 --mbcache=512 --rxq=1 --txq=1 --nb-cores=1 -i -a --rss-udp --record-core-cycles --record-burst-stats
# 运行一会后bps的速率上来了
$ show port stats all
######################## NIC statistics for port 0 ########################
RX-packets: 1160482282 RX-missed: 0 RX-bytes: 167907031020
RX-errors: 0
RX-nombuf: 0
TX-packets: 549941467 TX-errors: 0 TX-bytes: 118237415405
Throughput (since last show)
Rx-pps: 9645166 Rx-bps: 8980049144
Tx-pps: 2475415 Tx-bps: 4257714176
############################################################################
######################## NIC statistics for port 1 ########################
RX-packets: 549941971 RX-missed: 0 RX-bytes: 118237523765
RX-errors: 0
RX-nombuf: 0
TX-packets: 1160484118 TX-errors: 0 TX-bytes: 167907244720
Throughput (since last show)
Rx-pps: 2475444 Rx-bps: 4257764648
Tx-pps: 9645255 Tx-bps: 8980132160
############################################################################
$ stop
Telling cores to stop...
Waiting for lcores to finish...
---------------------- Forward statistics for port 0 ----------------------
RX-packets: 1238531580 RX-dropped: 0 RX-total: 1238531580
TX-packets: 569983390 TX-dropped: 0 TX-total: 569983390
RX-bursts : 4050218997 [95% of 0 pkts + 1% of 4 pkts + 0% of 8 pkts + 4% of other]
TX-bursts : 85526266 [0% of 0 pkts + 41% of 4 pkts + 35% of 8 pkts + 24% of other]
----------------------------------------------------------------------------
---------------------- Forward statistics for port 1 ----------------------
RX-packets: 569983390 RX-dropped: 0 RX-total: 569983390
TX-packets: 1238531580 TX-dropped: 0 TX-total: 1238531580
RX-bursts : 4050218997 [97% of 0 pkts + 0% of 4 pkts + 0% of 8 pkts + 3% of other]
TX-bursts : 170070708 [0% of 0 pkts + 25% of 4 pkts + 17% of 8 pkts + 58% of other]
----------------------------------------------------------------------------
+++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++
RX-packets: 1808514970 RX-dropped: 0 RX-total: 1808514970
TX-packets: 1808514970 TX-dropped: 0 TX-total: 1808514970
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CPU cycles/packet=127.91 (busy cycles=231332666074 / total io packets=1808514970) at 2995 MHz Clock
Done.
# CPU cycles/packet 的值越低 速度越快
# 使用双队列双核心
$ sudo dpdk-testpmd -c 0x0e -n 2 -a 0000:01:00.0 -a 0000:01:00.1 --socket-mem=8192,0 --huge-dir=/mnt/huge -- --port-numa-config=0,0,1,0 --socket-num=0 --burst=512 --txd=1024 --rxd=1024 --mbcache=512 --rxq=2 --txq=2 --nb-cores=2 -i -a --rss-udp --record-core-cycles --record-burst-stats
######################## NIC statistics for port 0 ########################
RX-packets: 1963422904 RX-missed: 0 RX-bytes: 227397490290
RX-errors: 0
RX-nombuf: 0
TX-packets: 771007421 TX-errors: 0 TX-bytes: 158589920420
Throughput (since last show)
Rx-pps: 8680468 Rx-bps: 7330440192
Tx-pps: 3155208 Tx-bps: 5015199184
############################################################################
######################## NIC statistics for port 1 ########################
RX-packets: 771008150 RX-missed: 0 RX-bytes: 158590065990
RX-errors: 0
RX-nombuf: 0
TX-packets: 1963424849 TX-errors: 0 TX-bytes: 227397699060
Throughput (since last show)
Rx-pps: 3155306 Rx-bps: 5015356408
Tx-pps: 8680703 Tx-bps: 7330649984
############################################################################
$ stop
Telling cores to stop...
Waiting for lcores to finish...
------- Forward Stats for RX Port= 0/Queue= 0 -> TX Port= 1/Queue= 0 -------
RX-packets: 1552299548 TX-packets: 1552299548 TX-dropped: 0
RX-bursts : 3193194151 [93% of 0 pkts + 0% of 6 pkts + 0% of 4 pkts + 7% of other]
TX-bursts : 200024644 [0% of 0 pkts + 12% of 6 pkts + 10% of 4 pkts + 78% of other]
------- Forward Stats for RX Port= 1/Queue= 0 -> TX Port= 0/Queue= 0 -------
RX-packets: 495868456 TX-packets: 495868456 TX-dropped: 0
RX-bursts : 3193194151 [94% of 0 pkts + 2% of 4 pkts + 0% of 1 pkts + 4% of other]
TX-bursts : 164737073 [0% of 0 pkts + 49% of 4 pkts + 17% of 1 pkts + 34% of other]
------- Forward Stats for RX Port= 0/Queue= 1 -> TX Port= 1/Queue= 1 -------
RX-packets: 425900739 TX-packets: 425900739 TX-dropped: 0
RX-bursts : 4052540020 [97% of 0 pkts + 1% of 4 pkts + 0% of 8 pkts + 2% of other]
TX-bursts : 87887339 [0% of 0 pkts + 71% of 4 pkts + 22% of 8 pkts + 7% of other]
------- Forward Stats for RX Port= 1/Queue= 1 -> TX Port= 0/Queue= 1 -------
RX-packets: 280671731 TX-packets: 280671731 TX-dropped: 0
RX-bursts : 4052540020 [98% of 0 pkts + 0% of 4 pkts + 0% of 8 pkts + 2% of other]
TX-bursts : 52020213 [0% of 0 pkts + 51% of 4 pkts + 38% of 8 pkts + 11% of other]
---------------------- Forward statistics for port 0 ----------------------
RX-packets: 1978200287 RX-dropped: 0 RX-total: 1978200287
TX-packets: 776540187 TX-dropped: 0 TX-total: 776540187
----------------------------------------------------------------------------
---------------------- Forward statistics for port 1 ----------------------
RX-packets: 776540187 RX-dropped: 0 RX-total: 776540187
TX-packets: 1978200287 TX-dropped: 0 TX-total: 1978200287
----------------------------------------------------------------------------
+++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++
RX-packets: 2754740474 RX-dropped: 0 RX-total: 2754740474
TX-packets: 2754740474 TX-dropped: 0 TX-total: 2754740474
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CPU cycles/packet=187.93 (busy cycles=517694727250 / total io packets=2754740474) at 2995 MHz Clock
Done.
# CPU cycles/packet的值变高了
# 使用双队列4核心
$ sudo dpdk-testpmd -c 0x3e -n 2 -a 0000:01:00.0 -a 0000:01:00.1 --socket-mem=8192,0 --huge-dir=/mnt/huge -- --port-numa-config=0,0,1,0 --socket-num=0 --burst=512 --txd=1024 --rxd=1024 --mbcache=512 --rxq=2 --txq=2 --nb-cores=4 -i -a --rss-udp --record-core-cycles --record-burst-stats
######################## NIC statistics for port 0 ########################
RX-packets: 935575414 RX-missed: 0 RX-bytes: 119383707435
RX-errors: 0
RX-nombuf: 0
TX-packets: 382552946 TX-errors: 0 TX-bytes: 82248883390
Throughput (since last show)
Rx-pps: 8376976 Rx-bps: 6764635816
Tx-pps: 1963665 Tx-bps: 3377504776
############################################################################
######################## NIC statistics for port 1 ########################
RX-packets: 382553291 RX-missed: 0 RX-bytes: 82248957565
RX-errors: 0
RX-nombuf: 0
TX-packets: 935576714 TX-errors: 0 TX-bytes: 119383845335
Throughput (since last show)
Rx-pps: 1963622 Rx-bps: 3377429944
Tx-pps: 8376748 Tx-bps: 6764465072
############################################################################
$ stop
Telling cores to stop...
Waiting for lcores to finish...
------- Forward Stats for RX Port= 0/Queue= 0 -> TX Port= 1/Queue= 0 -------
RX-packets: 709043179 TX-packets: 709043179 TX-dropped: 0
RX-bursts : 4249645726 [97% of 0 pkts + 0% of 4 pkts + 0% of 6 pkts + 3% of other]
TX-bursts : 101035564 [0% of 0 pkts + 15% of 4 pkts + 11% of 6 pkts + 74% of other]
------- Forward Stats for RX Port= 0/Queue= 1 -> TX Port= 1/Queue= 1 -------
RX-packets: 267878371 TX-packets: 267878371 TX-dropped: 0
RX-bursts : 401207470 [83% of 0 pkts + 16% of 4 pkts + 0% of 1 pkts + 1% of other]
TX-bursts : 67906564 [0% of 0 pkts + 97% of 4 pkts + 1% of 1 pkts + 2% of other]
------- Forward Stats for RX Port= 1/Queue= 1 -> TX Port= 0/Queue= 1 -------
RX-packets: 393491779 TX-packets: 393491779 TX-dropped: 0
RX-bursts : 338334978 [79% of 0 pkts + 10% of 4 pkts + 8% of 8 pkts + 3% of other]
TX-bursts : 68802993 [0% of 0 pkts + 51% of 4 pkts + 40% of 8 pkts + 9% of other]
---------------------- Forward statistics for port 0 ----------------------
RX-packets: 976921550 RX-dropped: 0 RX-total: 976921550
TX-packets: 393491779 TX-dropped: 0 TX-total: 393491779
----------------------------------------------------------------------------
---------------------- Forward statistics for port 1 ----------------------
RX-packets: 393491779 RX-dropped: 0 RX-total: 393491779
TX-packets: 976921550 TX-dropped: 0 TX-total: 976921550
----------------------------------------------------------------------------
+++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++
RX-packets: 1370413329 RX-dropped: 0 RX-total: 1370413329
TX-packets: 1370413329 TX-dropped: 0 TX-total: 1370413329
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CPU cycles/packet=190.88 (busy cycles=261585703810 / total io packets=1370413329) at 2995 MHz Clock
Done.
# 值变得更高了,难道不是核心和队列越多,速率越快,值越低吗?
# 查看转发配置
$ show config fwd
io packet forwarding - ports=2- cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native
Logical Core 2 (socket 0) forwards packets on 2 streams:
RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
$ set nbcore 2
$ show config fwd
io packet forwarding - ports=2 - cores=2 - streams=2 - NUMA support enabled, MP allocation mode: native
Logical Core 2 (socket 0) forwards packets on 1 streams:
RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
Logical Core 3 (socket 0) forwards packets on 1 streams:
RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
$ start tx_first
$ show port stats all
######################## NIC statistics for port 0 ########################
RX-packets: 1241637071 RX-missed: 0 RX-bytes: 108634053760
RX-errors: 0
RX-nombuf: 0
TX-packets: 262495460 TX-errors: 0 TX-bytes: 56436523900
Throughput (since last show)
Rx-pps: 8736851 Rx-bps: 7198983920
Tx-pps: 2723829 Tx-bps: 4684986896
############################################################################
######################## NIC statistics for port 1 ########################
RX-packets: 262496270 RX-missed: 0 RX-bytes: 56436698050
RX-errors: 0
RX-nombuf: 0
TX-packets: 1241639599 TX-errors: 0 TX-bytes: 108634314395
Throughput (since last show)
Rx-pps: 2722932 Rx-bps: 4683443888
Tx-pps: 8733848 Tx-bps: 7196513536
############################################################################
######################## NIC statistics for port 0 ########################
RX-packets: 21101617 RX-missed: 0 RX-bytes: 2036858462
RX-errors: 0
RX-nombuf: 0
TX-packets: 21464118 TX-errors: 0 TX-bytes: 2076719046
Throughput (since last show)
Rx-pps: 870386 Rx-bps: 675420272
Tx-pps: 870036 Tx-bps: 675148640
############################################################################
######################## NIC statistics for port 1 ########################
RX-packets: 21464450 RX-missed: 0 RX-bytes: 2076751250
RX-errors: 0
RX-nombuf: 0
TX-packets: 21101949 TX-errors: 0 TX-bytes: 2036890703
Throughput (since last show)
Rx-pps: 869990 Rx-bps: 675112664
Tx-pps: 870342 Tx-bps: 675385536
############################################################################
两次启动速率都不是很稳定,这是为什么呢?
SR-IOV
如果需要启用sr-iov, sr-iov大概是将pci网卡设备虚拟化出一个虚拟网卡,这样就相当于多出来一个网卡了,可以通供给虚拟机使用什么的,是不是不需要啊?
在只有一张网卡的情况下,这个网卡不能既被DPDK接管,同时被操作系统所使用。这个时候一般只能通过创建虚拟机,在虚拟机中运行DPDK接管virtio的虚拟网卡。
最近才发现了SR-IOV技术,可以在PCI层面虚拟网卡,不需要创建虚拟机,这个虚拟网卡直接就可以被DPDK接管,而原来的物理网卡还可以正常使用
上面这句话的意思是,只有一张网卡,intel的网卡如果被dpdk接管就不能作为普通网卡与外界通信了,但是又没有另一张物理网卡,或者是主机上没有多余的pci插槽了
这时候又想作为普通网卡与外界通信,又想被dpdk接管,就可以使用SR-IOV技术将物理网卡虚拟出一个虚拟网卡,虚拟出来的网卡被dpdk接管使用,物理网卡作为普通网卡使用
还有一种情况就是在一台主机上需要创建多个虚拟机,但是网卡只有一张,可以通过sr-iov技术虚拟多个网卡,每一个网卡被分配到不同的虚拟机中,在加上dpdk技术就可以实现高速通信
SR-IOV的全称是Single Root I/O Virtualization。
虚拟机中的网卡看起来是真实的硬件,实际则是宿主机虚拟化出来的设备,也就是运行的软件程序;这也意味着,虚拟设备是需要CPU去运行的,这样设备的性能会随着宿主机性能而改变,可能会产生额外的延时。
VT-D技术可以将物理机的PCIe设备直接分配给虚拟机,让虚拟机直接控制硬件,来避免上述问题。但是虚拟机会独占直通的PCIe设备,如果一台宿主机上有多个虚拟机,那就要求对应数量的物理网卡,这显然不现实。
为解决这样的问题,Intel提出来SR-IOV技术,该技术最初应用在网卡上。简单来讲,就是将一个物理网卡虚拟出多个轻量化的PCIe物理设备,再分配给虚拟机使用。
启用SR-IOV技术,可以大大减轻宿主机的CPU负荷,提高网络性能、降低网络延时,也避免了PCI-passthrough下各个物理网卡被各个容器独占的问题。
不知道这样理解是否正确? 所以如果没有虚拟机或者需要使用多个网卡的场景中,是不是不需要开启SR-IOV呢
虚拟出来的网卡也可以进行数据通信,那么多出来的网卡可以交给不同的cpu核心
以下是ChatGPT3.5回答的
如果本身网卡支持多队列(Multi-Queue),那么在某些情况下可能不需要使用SR-IOV技术。
多队列网卡可以将网络流量分配到多个队列中,每个队列可以独立地处理网络流量,从而提高网络处理性能。在这种情况下,可以使用DPDK来分配接收队列和发送队列,从而实现高性能的网络处理。
SR-IOV技术主要用于将一个物理网卡虚拟成多个虚拟网卡,每个虚拟网卡可以独立地处理网络流量。这种技术通常用于虚拟机或容器环境中,需要将网络流量路由到正确的虚拟机或容器。
如果本身网卡支持多队列,并且不需要将网络流量路由到虚拟机或容器,那么可能不需要使用SR-IOV技术。例如:
在 bare-metal 服务器上运行的应用程序,使用多队列网卡可以提高网络处理性能,无需使用SR-IOV技术。
在容器环境中,如果每个容器都可以直接访问物理网卡,并且不需要将网络流量路由到其他容器,那么可能不需要使用SR-IOV技术。
但是,在以下情况下,仍然需要使用SR-IOV技术:
需要将网络流量路由到虚拟机或容器。
需要在多个虚拟机或容器之间共享物理网卡。
需要在虚拟机或容器之间实现网络隔离和安全性。
因此,是否需要使用SR-IOV技术取决于具体的应用场景和需求。如果需要将网络流量路由到虚拟机或容器,或者需要在多个虚拟机或容器之间共享物理网卡,那么SR-IOV技术可能是必要的。
所以一个网卡本身支持多队列网卡时,SR-IOV技术好像暂时可以不被使用,DPDK技术可以指定收发队列
$ sudo mst start
$ sudo mlxconfig -d /dev/mst/mt4119_pciconf0 query | grep SRIOV_EN
SRIOV_EN False(0)
# 官方建议不要超过16个
$ sudo mlxconfig -d /dev/mst/mt4119_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=16
Device #1:
----------
Device type: ConnectX5
Name: MCX556A-ECA_Ax
Description: ConnectX-5 VPI adapter card; EDR IB (100Gb/s) and 100GbE; dual-port QSFP28; PCIe3.0 x16; tall bracket; ROHS R6
Device: /dev/mst/mt4119_pciconf0
Configurations: Next Boot New
SRIOV_EN False(0) True(1)
NUM_OF_VFS 0 16
Apply new Configuration? (y/n) [n] : y
Applying... Done!
-I- Please reboot machine to load new configurations.
$ sudo mlxfwreset -d /dev/mst/mt4119_pciconf0 reset
Minimal reset level for device, /dev/mst/mt4119_pciconf0:
3: Driver restart and PCI reset
Continue with reset?[y/N] y
-I- Sending Reset Command To Fw -Done
-I- Stopping Driver -Done
-I- Resetting PCI -Done
-I- Starting Driver -Done
-I- Restarting MST -Done
-I- FW was loaded successfully.
$ sudo /etc/init.d/openibd restart
$ reboot
$ lspci | grep Mellanox
0000:01:00.0 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
0000:01:00.1 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
$ sudo chmod 666 /sys/class/infiniband/mlx5_0/device/sriov_numvfs
$ sudo echo 2 > /sys/class/infiniband/mlx5_0/device/sriov_numvfs
$ lspci | grep Mellanox
0000:01:00.0 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
0000:01:00.1 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5]
0000:01:00.2 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function]
0000:01:00.3 Ethernet controller: Mellanox Technologies MT27800 Family [ConnectX-5 Virtual Function]
网卡多队列
# 可以使用lspci查询网卡的最大支持多少个队列
$ sudo lspci -vvvs 01:00.0 | grep MSI-X
Capabilities: [9c] MSI-X: Enable+ Count=64 Masked-
# 可以看到网卡最大支持64个队列
$ sudo ethtool -l enp1s0f0np0
Channel parameters for enp1s0f0np0:
Pre-set maximums:
RX: 0
TX: 0
Other: 0
Combined: 12
Current hardware settings:
RX: 0
TX: 0
Other: 0
Combined: 12
# Combined 代表了当前网卡启动的队列数,这个数值我怀疑和cpu的核心数有关,因为网卡本身支持64个队列,默认的情况下只开启了12个和CPU的核心数正好相等,但这都是我个人的猜测。
pktgen
找不到numa库,在确定安装了 libnuma-dev情况下
安装最新的cmake后修改pktgen下的app目录的meson.build文件
$ sudo vim app/meson.build
deps += [cc.find_library('numa', required: true)]
#deps += [dependency('numa', required: true)]
pcap-config found: NO
$ sudo apt-get install libpcap-dev libbsd-dev doxygen python3-sphinx
编译安装
我看有的文章说DPDK和pktgen需要版本配合,我DPDK是23.11,pktgen是23.10,可以使用
$ wget https://git.dpdk.org/apps/pktgen-dpdk/snapshot/pktgen-dpdk-pktgen-23.10.0.tar.gz
$ cd pktgen-dpdk-pktgen-23.10.0
$ meson setup build
$ cd build
# 编译
$ ninja -j4
# 安装
$ meson install
使用
$ sudo pktgen -l 2-10 -n 4 --proc-type auto --socket-mem 8192 -- -P -T -m "[3-4:5-6].0,[7-8:9-10].1"
MBits/s Rx/Tx : 0/27,848 15,023/0 150,23/27,848
通过以上信息可以看到发送有27,848M大概是27个G每秒,接收15,023M大概是15个G每秒,接收的速率为什么比发送的少了这么多呢?
设置发送的包长为1024
$ sudo pktgen -l 2-18 -n 4 --proc-type auto --socket-mem 8192 -- -P -T -m "[3-6:7-10].0,[11-14:15-18].1"
# 进入pktgen命令行以后设置两个端口的发包长度
> set 0 size 1024
> set 1 size 1024
> start 0,1
在设置了发包长度为1024后两个端口的收发速率均达到了100G网卡的理论速率
网卡固件更新
安装DPDK不需要更新网卡固件,所以此章节只是记录,无需操作
[ 11.098195] mlx5_core 0000:01:00.0: poll_health:739:(pid 847): device’s health compromised - reached miss count
[ 11.098215] mlx5_core 0000:01:00.0: print_health_info:386:(pid 847): assert_var[0] 0x00000000
[ 11.098226] mlx5_core 0000:01:00.0: print_health_info:386:(pid 847): assert_var[1] 0x00000000
[ 11.098234] mlx5_core 0000:01:00.0: print_health_info:386:(pid 847): assert_var[2] 0x00000000
[ 11.098242] mlx5_core 0000:01:00.0: print_health_info:386:(pid 847): assert_var[3] 0x00000000
[ 11.098247] mlx5_core 0000:01:00.0: print_health_info:386:(pid 847): assert_var[4] 0x00000000
[ 11.098251] mlx5_core 0000:01:00.0: print_health_info:389:(pid 847): assert_exit_ptr 0x00985500
[ 11.098259] mlx5_core 0000:01:00.0: print_health_info:391:(pid 847): assert_callra 0x00989f70
[ 11.098276] mlx5_core 0000:01:00.0: print_health_info:394:(pid 847): fw_ver 16.26.4012
[ 11.098283] mlx5_core 0000:01:00.0: print_health_info:395:(pid 847): hw_id 0x0000020d
[ 11.098291] mlx5_core 0000:01:00.0: print_health_info:396:(pid 847): irisc_index 4
[ 11.098303] mlx5_core 0000:01:00.0: print_health_info:397:(pid 847): synd 0x1: firmware internal error
[ 11.098312] mlx5_core 0000:01:00.0: print_health_info:399:(pid 847): ext_synd 0x8a02
[ 11.098320] mlx5_core 0000:01:00.0: print_health_info:401:(pid 847): raw fw_ver 0x101a0fac
[ 11.866192] mlx5_core 0000:01:00.1: poll_health:739:(pid 0): device’s health compromised - reached miss count
[ 11.866217] mlx5_core 0000:01:00.1: print_health_info:386:(pid 0): assert_var[0] 0x00000000
[ 11.866224] mlx5_core 0000:01:00.1: print_health_info:386:(pid 0): assert_var[1] 0x00000000
[ 11.866232] mlx5_core 0000:01:00.1: print_health_info:386:(pid 0): assert_var[2] 0x00000000
[ 11.866240] mlx5_core 0000:01:00.1: print_health_info:386:(pid 0): assert_var[3] 0x00000000
[ 11.866245] mlx5_core 0000:01:00.1: print_health_info:386:(pid 0): assert_var[4] 0x00000000
[ 11.866249] mlx5_core 0000:01:00.1: print_health_info:389:(pid 0): assert_exit_ptr 0x00985500
[ 11.866257] mlx5_core 0000:01:00.1: print_health_info:391:(pid 0): assert_callra 0x00989f70
[ 11.866271] mlx5_core 0000:01:00.1: print_health_info:394:(pid 0): fw_ver 16.26.4012
[ 11.866278] mlx5_core 0000:01:00.1: print_health_info:395:(pid 0): hw_id 0x0000020d
[ 11.866286] mlx5_core 0000:01:00.1: print_health_info:396:(pid 0): irisc_index 4
[ 11.866295] mlx5_core 0000:01:00.1: print_health_info:397:(pid 0): synd 0x1: firmware internal error
[ 11.866303] mlx5_core 0000:01:00.1: print_health_info:399:(pid 0): ext_synd 0x8a02
[ 11.866310] mlx5_core 0000:01:00.1: print_health_info:401:(pid 0): raw fw_ver 0x101a0fac
以上报错信息在dmesg中呈现,在Device’s health compromised: firmware internal error这个论坛中有人问到过这个问题,评论中有人指出虽然有这个报错信息但是不会影响运行时的状态,所以不用担心。
我更新了最新的固件这个报错信息还是存在所以在不影响使用的前提下就先不管这个错误了。
查询到的PSID为MT_0000000008,那么在固件下载网址中寻找PSID为MT_0000000008的下载就可以了。
升级固件
在上面的网址中找到网卡相应的型号,然后选择与当前网卡的PSID一致的固件下载,使用以下命令查询当前网卡的PSID
将下载好的zip包解压后会得到一个bin文件
$ sudo flint -d /dev/mst/mt4119_pciconf0 -i ./fw-ConnectX5-rel-16_35_4030-MCX556A-ECA_Ax-UEFI-14.29.15-FlexBoot-3.6.902.bin burn
Current FW version on flash: 16.26.4012
New FW version: 16.35.4030
FSMST_INITIALIZE - OK
Writing Boot image component - OK
Restoring signature - OK
-I- To load new FW run mlxfwreset or reboot machine.
# 升级完成以后重启网卡
$ sudo mlxfwreset -d /dev/mst/mt4119_pciconf0 reset
# 再次查询网卡固件版本
$ sudo flint -d /dev/mst/mt4119_pciconf0 query
Image type: FS4
FW Version: 16.35.4030
FW Release Date: 27.6.2024
Product Version: 16.35.4030
Rom Info: type=UEFI version=14.29.15 cpu=AMD64
type=PXE version=3.6.902 cpu=AMD64
Description: UID GuidsNumber
Base GUID: 0c42a10300ac0b66 8
Base MAC: 0c42a1ac0b66 8
Image VSD: N/A
Device VSD: N/A
PSID: MT_0000000008
Security Attributes: N/A
网卡固件版本已经升级到最新了。