该文章目标是得出DPDK绑定网卡脚本,只需修改个别参数即可使用,因此涉及到得其他流程不再具体呈现(如dpdk编译安装,巨页内存配置等)。
针对igb_uio
驱动(对应DPDK版本16.11, 操作系统CentOS 7.2)以及vfio-pci
驱动(对应DPDK版本20.11,操作系统CentOS 8.4)这两个进行对比说明。
DPDK绑定网卡的简单步骤如下:
- 查看网卡名(ifconfig命令查看);
- 挂载dpdk驱动(
igb_uio
或者vfio-pci
驱动); - 将网卡
down
掉(ifconfig xxx down); - 使用
dpdk-devbind.py
将网卡绑定到指定驱动中(igb_uio
或者vfio-pci
驱动); - 使用
dpdk-devbind.py -s
查看绑定网卡信息;
DPDK解绑网卡的简单步骤如下:
- 获取网卡名;
- 获取网卡
bus-info
信息; - 获取网卡原始驱动类型;
- 使用
dpdk-devbind.py
将网卡从刚才绑定的驱动中解绑出来; - 在使用
dpdk-devbind.py
将网卡绑定为第3
步骤中得到的网卡类型(复原为原始网卡的驱动类型); - 卸载dpdk驱动(
igb_uio
或者vfio-pci
驱动); - 使用
dpdk-devbind.py -s
查看绑定网卡信息; - 将网卡
up
起来(ifconfig xxx up);
1、网卡驱动
1.1、查看网卡名称
[root@LFTF ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.22.137 netmask 255.255.255.0 broadcast 192.168.22.255
inet6 fe80::20c:29ff:febe:75a8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:be:75:a8 txqueuelen 1000 (Ethernet)
RX packets 1381 bytes 153689 (150.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1096 bytes 122554 (119.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:be:75:b2 txqueuelen 1000 (Ethernet)
RX packets 80 bytes 9707 (9.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
ens37
即为要绑定的网卡
1.2、查看网卡驱动
[root@LFTF ~]# ethtool -i ens37
driver: e1000
version: 7.3.21-k8-NAPI
firmware-version:
expansion-rom-version:
bus-info: 0000:02:05.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
其中driver: e1000
即为ens37
网卡驱动类型。相关的,还有ixgbe、igbe、i40e
等驱动类型。
这里要记录驱动类型driver: e1000
和对应的pci地址bus-info:0000:02:05.0
这两条信息。
2、绑定网卡
2.1、获取网卡名称
[root@LFTF ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.22.137 netmask 255.255.255.0 broadcast 192.168.22.255
inet6 fe80::20c:29ff:febe:75a8 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:be:75:a8 txqueuelen 1000 (Ethernet)
RX packets 1381 bytes 153689 (150.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1096 bytes 122554 (119.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:be:75:b2 txqueuelen 1000 (Ethernet)
RX packets 80 bytes 9707 (9.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
ens37
即为要绑定的网卡
2.2、挂载驱动
igb_uio
驱动和vfio-pci
驱动使用一个即可,下面只是介绍挂载方法。
2.1.1、挂载igb_uio驱动
首先查看是否已经挂载igb_uio
驱动
[root@LFTF kmod]# lsmod | grep igb_uio
[root@LFTF kmod]#
- 1
- 2
未查询到~
编译dpdk-16.11
版本代码,如果选择的是x86_64-native-linuxapp-gcc
编译器,会在dpdk-16.11
目录下生成一个x86_64-native-linuxapp-gcc
文件夹,如下所示:
[root@LFTF ~]# cd /home/dpdk-16.11.5/x86_64-native-linuxapp-gcc
[root@LFTF x86_64-native-linuxapp-gcc]# pwd
/home/dpdk-16.11.5/x86_64-native-linuxapp-gcc
[root@LFTF x86_64-native-linuxapp-gcc]#
[root@LFTF x86_64-native-linuxapp-gcc]# ls
app build include kmod lib Makefile
[root@LFTF x86_64-native-linuxapp-gcc]# cd kmod
[root@LFTF kmod]# ls
igb_uio.ko rte_kni.ko
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
加载dpdk的igb_uio驱动,首先需要加载完uio内核驱动,然后再加载kmod
目录中igb_uio驱动模块,如下所示:
[root@LFTF kmod]# modprobe uio
[root@LFTF kmod]# insmod ./igb_uio.ko
- 1
- 2
查看igb_uio
驱动是否已经加载
[root@LFTF kmod]# lsmod | grep uio
igb_uio 13224 0
uio 19259 1 igb_uio
- 1
- 2
- 3
已经加载成功!
卸载网卡驱动方法
[root@LFTF kmod]# rmmod igb_uio
- 1
2.1.2、挂载vfio-pci驱动
UIO
驱动和VFIO
驱动区别如下:
- VFIO是一个可以安全地把设备I/O、中断、DMA等暴露到用户空间(userspace),从而可以在用户空间完成设备驱动的框架。用户空间直接设备访问,虚拟机设备分配可以获得更高的IO性能。
- 依赖于IOMMU. vfio-pci
- 相比于UIO,VFIO更为强健和安全
首先查看是否已经挂载vfio-pci
驱动
[root@LFTF ~]# lsmod | grep vfio
[root@LFTF ~]#
- 1
- 2
未查询到~
修改grub
配置,开启vfio
支持,检查GRUB
配置:
#内核需要配置支持Intel® VT-x、VT-d,内核通过如下命令查看:
[root@LFTF ~]# cat /proc/cmdline | grep iommu=pt
[root@LFTF ~]# cat /proc/cmdline | grep intel_iommu=on
- 1
- 2
- 3
- 4
没发现则需要添加:
vim /etc/default/grub
#在下面行中添加:iommu=pt intel_iommu=on
GRUB_CMDLINE_LINUX=
#现在变成了:
GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet iommu=pt intel_iommu=on "
# 更新配置和重启
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
验证下:
[root@LFTF ~]# cat /proc/cmdline | grep intel_iommu=on
BOOT_IMAGE=(hd0,msdos1)/vmlinuz-4.18.0-240.el8.x86_64 root=/dev/mapper/cl-root ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet iommu=pt intel_iommu=on
[root@LFTF ~]# cat /proc/cmdline | grep iommu=pt
BOOT_IMAGE=(hd0,msdos1)/vmlinuz-4.18.0-240.el8.x86_64 root=/dev/mapper/cl-root ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet iommu=pt intel_iommu=on
- 1
- 2
- 3
- 4
加载网卡驱动
[root@LFTF ~]# modprobe vfio
[root@LFTF ~]# modprobe vfio-pci
- 1
- 2
查看
[root@LFTF ~]# lsmod | grep vfio_pci
vfio_pci 61440 0
vfio_virqfd 16384 1 vfio_pci
vfio 36864 2 vfio_iommu_type1,vfio_pci
irqbypass 16384 2 vfio_pci,kvm
- 1
- 2
- 3
- 4
- 5
卸载网卡驱动方法
[root@LFTF ~]# rmmod vfio-pci
- 1
2.3、关闭网卡
再步骤1
中查记录网卡信息后,关闭网卡
[root@LFTF ~]# ifconfig down ens37
- 1
2.4、绑定网卡
dpdk16.11
版本到tools
目录下,dpdk20.11
版本到usertools
目录下。使用脚本./dpdk-devbind.py
绑定网卡
#DPDK16.11版本--将ens37网卡绑定到igb_uio驱动
[root@LFTF tools]# ./dpdk-devbind.py --bind=igb_uio ens37
- 1
- 2
#DPDK20.11版本--将ens37网卡绑定到vfio-pci驱动
[root@LFTF usertools]# ./dpdk-devbind.py --bind=vfio-pci ens37
- 1
- 2
2.5、查看网卡状态
DPDK16.11
版本–将ens37
网卡绑定到igb_uio
驱动之后网卡状态
[root@LFTF tools]# ./dpdk-devbind.py -s
Network devices using DPDK-compatible driver
============================================
0000:02:05.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' drv=igb_uio unused=e1000
Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens35 drv=e1000 unused=igb_uio *Active*
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
DPDK20.11
版本–将ens37
网卡绑定到vfio-pci
驱动驱动之后网卡状态
[root@LFTF usertools]# ./dpdk-devbind.py -s
Network devices using DPDK-compatible driver
============================================
0000:02:05.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' drv=vfio-pci unused=e1000
Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens35 drv=e1000 unused=vfio-pci *Active*
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3、解绑网卡
3.1、获取网卡名称
即为步骤2
中绑定的网卡名ens37
。(由于此时网卡已经由DPDK
驱动接管,因此使用系统命令ifconfig
获取不到绑定网卡的基本信息)
3.2、获取网卡原始驱动类型
即为步骤1.2
中得到的驱动类型driver: e1000
。
3.3、获取网卡bus-info
信息
即为步骤1.2
中得到的bus-info:0000:02:05.0
3.4、将网卡从DPDK驱动中解绑
dpdk16.11
版本到tools
目录下,dpdk20.11
版本到usertools
目录下。使用脚本./dpdk-devbind.py
解绑网卡
#DPDK16.11版本--将ens37网卡解绑
[root@LFTF tools]# ./dpdk-devbind.py -u 0000:02:05.0
- 1
- 2
#DPDK20.11版本--将ens37网卡解绑
[root@LFTF usertools]#./dpdk-devbind.py -u 0000:02:05.0
- 1
- 2
3.5、将网卡绑定为网卡原始驱动
#DPDK16.11版本--将ens37网卡绑定到原始e1000驱动
[root@LFTF tools]# ./dpdk-devbind.py -b e1000 0000:02:05.0
- 1
- 2
#DPDK20.11版本--将ens37网卡解绑
[root@LFTF usertools]#./dpdk-devbind.py -b e1000 0000:02:05.0
- 1
- 2
3.6、卸载驱动
3.6.1、卸载igb_uio驱动
首先查看是否已经挂载igb_uio
驱动
[root@LFTF kmod]# lsmod | grep uio
igb_uio 13224 0
uio 19259 1 igb_uio
- 1
- 2
- 3
存在igb_uio
驱动,开始卸载~
[root@LFTF kmod]# rmmod igb_uio
- 1
3.6.2、卸载vfio-pci驱动
首先查看是否已经挂载vfio-pci
驱动
[root@LFTF ~]# lsmod | grep vfio_pci
vfio_pci 61440 0
vfio_virqfd 16384 1 vfio_pci
vfio 36864 2 vfio_iommu_type1,vfio_pci
irqbypass 16384 2 vfio_pci,kvm
- 1
- 2
- 3
- 4
- 5
存在vfio-pci
驱动,开始卸载~
[root@LFTF ~]# rmmod vfio-pci
- 1
3.7、查看网卡状态
DPDK16.11
版本–将ens37
网卡绑定到原始网卡驱动之后网卡状态
[root@LFTF tools]# ./dpdk-devbind.py -s
Network devices using DPDK-compatible driver
============================================
<none>
Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens33 drv=e1000 unused= *Active*
0000:02:05.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens37 drv=e1000 unused=
Other network devices
=====================
<none>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
DPDK20.11
版本–将ens37
网卡绑定到原始网卡驱动之后网卡状态
[root@LFTF usertools]# ./dpdk-devbind.py -s
Network devices using kernel driver
===================================
0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens33 drv=e1000 unused= *Active*
0000:02:05.0 '82545EM Gigabit Ethernet Controller (Copper) 100f' if=ens37 drv=e1000 unused=
No 'Baseband' devices detected
==============================
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
可以看到,此时网卡已经有系统网卡驱动接管
3.8、启动网卡
[root@LFTF ~]# ifconfig up ens37
- 1
4、绑定网卡和解绑网卡脚本
通过上面的步骤,我们可以把绑定网卡和解绑网卡所需要的脚本工具以及驱动整合到一个目录下,然后编写一个脚本来实现一键绑定指定的网卡以及解除绑定后的网卡。
根据上述步骤,将网卡绑定到igb_uio
驱动上比vfio-pci
驱动多出了一个igb_uio.ko
文件(/home/dpdk-16.11.5/x86_64-native-linuxapp-gcc/kmod
路径下)。因此以绑定到igb_uio
驱动为例,编写出一键绑定网卡的脚本。
首先将kmod
目录和tools
目录copy
到一个文件夹(一是为了写脚本的时候使用相对路径方便,二是不用包含过多dpdk相关文件便于移植使用),如下所示:
[root@LFTF dpdk_bind]# ls
kmod tools
[root@LFTF dpdk_bind]# ll kmod/
total 9176
-rwxr-xr-x. 1 root root 236431 Dec 14 20:14 igb_uio.ko
-rwxr-xr-x. 1 root root 9155150 Dec 14 20:14 rte_kni.ko
[root@LFTF dpdk_bind]# ll tools/
total 112
-rwxr-xr-x. 1 root root 3414 Dec 14 20:13 cpu_layout.py
-rwxr-xr-x. 1 root root 22764 Dec 14 20:13 dpdk-devbind-igb.py
-rwxr-xr-x. 1 root root 22764 Dec 14 20:13 dpdk-devbind-ixgbe.py
-rwxr-xr-x. 1 root root 22764 Dec 14 20:13 dpdk-devbind.py
-rwxr-xr-x. 1 root root 20082 Dec 14 20:13 dpdk-pmdinfo.py
-rwxr-xr-x. 1 root root 14634 Dec 14 20:13 dpdk-setup.sh
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
4.1、绑定网卡脚本
在dpdk_bind
目录下创建绑定网卡的脚本dpdk_setup.sh
[root@LFTF dpdk_bind]# ll
total 8
-rwxr-xr-x. 1 root root 435 Dec 14 20:13 dpdk_setup.sh
drwxr-xr-x. 2 root root 40 Dec 14 20:14 kmod
drwxr-xr-x. 2 root root 4096 Dec 14 20:13 tools
- 1
- 2
- 3
- 4
- 5
内容如下:
[root@LFTF dpdk_bind]# vim dpdk_setup.sh
#!/bin/sh
#网卡名
uio0=ens37
#uio1=ens38
#需要绑定的驱动类型igb_uio或者vfio-pci
pci_type=igb_uio
#挂载驱动
modprobe uio
insmod ./kmod/igb_uio.ko
#关闭网卡
ifconfig $uio0 down
#ifconfig $uio1 down
#绑定网卡到igb_uio
./tools/dpdk-devbind.py --bind=$pci_type $uio0
#./tools/dpdk-devbind.py --bind=$pci_type $uio1
#展示网卡绑定后的状态
./tools/dpdk-devbind.py --status
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
这里只需要修改要绑定的**网卡名和驱动类型**即可
4.2、解绑网卡脚本
在dpdk_bind
目录下创建解绑网卡的脚本dpdk_remove.sh
[root@LFTF dpdk_bind]# ll
total 8
-rwxr-xr-x. 1 root root 0 Dec 14 20:34 dpdk_remove.sh
-rwxr-xr-x. 1 root root 425 Dec 14 20:32 dpdk_setup.sh
drwxr-xr-x. 2 root root 40 Dec 14 20:14 kmod
drwxr-xr-x. 2 root root 4096 Dec 14 20:13 tools
- 1
- 2
- 3
- 4
- 5
- 6
内容如下:
[root@LFTF dpdk_bind]# vim dpdk_remove.sh
#!/bin/sh
#pci网卡地址 即bus-info值
pci0=0000:02:05.0
#pci1=0000:02:06.0
#网卡名
uio0=ens37
#uio1=ens38
#网卡原始驱动类型
pci_type=e1000
#将网卡从dpdk驱动中解绑
./tools/dpdk-devbind.py -u $pci0
#./tools/dpdk-devbind.py -u $pci1
#将网卡绑定为网卡原始驱动
./tools/dpdk-devbind.py -b $pci_type $pci0
#./tools/dpdk-devbind.py -b $pci_type $pci1
#展示网卡解绑后的状态
./tools/dpdk-devbind.py -s
#卸载相关驱动
rmmod igb_uio uio
#启动网卡
ifconfig $uio0 up
#ifconfig $uio1 up
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
这里需要修改的参数有pci网卡地址和网卡名和驱动类型
5、参考命令
#查看网卡原始驱动类型
[root@localhost ~]# ethtool -i ens37 | grep driver
driver: e1000
#查看网卡对应的bus-info值
[root@localhost ~]# ethtool -i ens37 | grep bus-info
bus-info: 0000:02:05.0
#查看网卡对应的传输速率(千兆or万兆)
[root@localhost ~]# ethtool ens37 | grep Speed
Speed: 1000Mb/s
[root@localhost ~]# ethtool en5s0 | grep Speed
Speed: 10000Mb/s
#查看网卡对应的NUMA节点
[root@localhost ~]# ethtool -i ens37 | grep bus-info
bus-info: 0000:02:05.0
[root@localhost ~]# cat /sys/bus/pci/devices/0000\:02\:05.0/numa_node
0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
6、网站链接
有关vfio-pci
这个驱动绑定脚本可以在下面链接中免费下载获取
7、总结
记得vfio
驱动挂载的时候需要修改grub
配置,开启vfio
支持。