​该文章目标是得出DPDK绑定网卡脚本,只需修改个别参数即可使用,因此涉及到得其他流程不再具体呈现(如dpdk编译安装,巨页内存配置等)。

针对igb_uio驱动(对应DPDK版本16.11, 操作系统CentOS 7.2)以及vfio-pci驱动(对应DPDK版本20.11,操作系统CentOS 8.4)这两个进行对比说明。

DPDK绑定网卡的简单步骤如下:

  1. 查看网卡名(ifconfig命令查看);
  2. 挂载dpdk驱动(igb_uio或者vfio-pci驱动);
  3. 将网卡down掉(ifconfig xxx down);
  4. 使用dpdk-devbind.py将网卡绑定到指定驱动中(igb_uio或者vfio-pci驱动);
  5. 使用dpdk-devbind.py -s查看绑定网卡信息;

DPDK解绑网卡的简单步骤如下:

  1. 获取网卡名;
  2. 获取网卡bus-info信息;
  3. 获取网卡原始驱动类型;
  4. 使用dpdk-devbind.py将网卡从刚才绑定的驱动中解绑出来;
  5. 在使用dpdk-devbind.py将网卡绑定为第3步骤中得到的网卡类型(复原为原始网卡的驱动类型);
  6. 卸载dpdk驱动(igb_uio或者vfio-pci驱动);
  7. 使用dpdk-devbind.py -s查看绑定网卡信息;
  8. 将网卡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这个驱动绑定脚本可以在下面链接中免费下载获取

DPDK绑定网卡解绑网卡脚本下载

7、总结

记得vfio驱动挂载的时候需要修改grub配置,开启vfio支持。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐