1 - 开启直通

开启直通功能

可以通过两种方式开启直通功能:

  1. 手工修改
  2. 用 pvetools 工具帮忙

准备工作

主板bios设置

必须先在主板 bios 中开启 cpu 的 VD-T 支持和虚拟化支持。

VD-T不支持就无法直通。intel 要 b75 以上芯片组才支持。也就是需要从 intel 4代酷睿处理器开始才支持。

虚拟机设置

在创建虚拟机时,芯片组一定要q35 。因为Q35,才能 PCIE 直通,否则就是 PCI 直通。

手工

开启 iommu

vi /etc/default/grub

修改 GRUB_CMDLINE_LINUX_DEFAULT,增加 intel_iommu=on 。使用 intel_iommu=on 后,开机会有内核crash,可以尝试加一个 iommu=pt。这样就是:

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_pstate=disable intel_iommu=on iommu=pt pcie_acs_override=downstream pci=realloc=off"

备注: 安装完成后的默认值是 GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_pstate=disable"

解释:

  • pcie_acs_override=downstream
  • pci=realloc=off

修改完成之后,更新 grub:

update-grub

设置虚拟化驱动

vi /etc/modules

增加以下内容:

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

备注: 安装完成后的默认值是空,仅有少量注释。

升级并更新配置:

update-initramfs -u -k all

之后重启机器。

pvetools

使用 pvetools 就简单了,只要在 pvetools 的菜单中选择 “配置PCI硬件直通” -》“配置开启物理机硬件直通支持”。

完成后重启机器。

检验

检验 iommu 是否开启

dmesg | grep -e DMAR -e IOMMU

正确开启时的输出会类似如下:

[    0.000000] Warning: PCIe ACS overrides enabled; This may allow non-IOMMU protected peer-to-peer DMA
[    0.033632] ACPI: DMAR 0x00000000BC4B0870 0000B8 (v01 INTEL  HSW      00000001 INTL 00000001)
[    0.033687] ACPI: Reserving DMAR table memory at [mem 0xbc4b0870-0xbc4b0927]
[    0.066765] DMAR: IOMMU enabled
[    0.186968] DMAR: Host address width 39
[    0.186972] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.186988] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap c0000020660462 ecap f0101a
[    0.186996] DMAR: DRHD base: 0x000000fed91000 flags: 0x1
[    0.187006] DMAR: dmar1: reg_base_addr fed91000 ver 1:0 cap d2008020660462 ecap f010da
[    0.187012] DMAR: RMRR base: 0x000000bc1d8000 end: 0x000000bc1e4fff
[    0.187017] DMAR: RMRR base: 0x000000bf000000 end: 0x000000cf1fffff
[    0.187024] DMAR-IR: IOAPIC id 8 under DRHD base  0xfed91000 IOMMU 1
[    0.187030] DMAR-IR: HPET id 0 under DRHD base 0xfed91000
[    0.187034] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[    0.188070] DMAR-IR: Enabled IRQ remapping in x2apic mode
[    0.634998] DMAR: No ATSR found
[    0.635001] DMAR: No SATC found
[    0.635004] DMAR: IOMMU feature pgsel_inv inconsistent
[    0.635008] DMAR: IOMMU feature sc_support inconsistent
[    0.635011] DMAR: IOMMU feature pass_through inconsistent
[    0.635014] DMAR: dmar0: Using Queued invalidation
[    0.635026] DMAR: dmar1: Using Queued invalidation
[    0.720415] DMAR: Intel(R) Virtualization Technology for Directed I/O
[   14.512740] i915 0000:00:02.0: [drm] DMAR active, disabling use of stolen memory

可以看到 “DMAR: IOMMU enabled” / “DMAR: Intel(R) Virtualization Technology for Directed I/O” 的字样,说明 IOMMU 开启成功。

执行命令:

dmesg | grep 'remapping'

如果看到类似如下 “Enabled IRQ remapping in x2apic mode” 内容,也说明 IOMMU 开启成功:

[    0.187034] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[    0.188070] DMAR-IR: Enabled IRQ remapping in x2apic mode

或者执行

dmesg | grep iommu

如果能看到类似内容,也说明 IOMMU 开启成功:

[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-6.2.16-3-pve root=/dev/mapper/pve-root ro quiet intel_pstate=disable intel_iommu=on iommu=pt pcie_acs_override=downstream pci=realloc=off
[    0.066508] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-6.2.16-3-pve root=/dev/mapper/pve-root ro quiet intel_pstate=disable intel_iommu=on iommu=pt pcie_acs_override=downstream pci=realloc=off
[    0.558404] iommu: Default domain type: Passthrough (set via kernel command line)
[    0.719593] pci 0000:00:02.0: Adding to iommu group 0
[    0.719693] pci 0000:00:00.0: Adding to iommu group 1
[    0.719725] pci 0000:00:01.0: Adding to iommu group 2
[    0.719755] pci 0000:00:01.1: Adding to iommu group 3
......
[    0.720223] pci 0000:05:00.0: Adding to iommu group 17
[    0.720252] pci 0000:06:00.0: Adding to iommu group 18
[    0.720278] pci 0000:08:00.0: Adding to iommu group 19

还可以执行命令

find /sys/kernel/iommu_groups/ -type l 

如果能看到很多直通组,说明开启成功:

/sys/kernel/iommu_groups/17/devices/0000:05:00.0
/sys/kernel/iommu_groups/7/devices/0000:00:1c.0
/sys/kernel/iommu_groups/15/devices/0000:02:00.0
/sys/kernel/iommu_groups/5/devices/0000:00:16.0
......
/sys/kernel/iommu_groups/19/devices/0000:08:00.0
/sys/kernel/iommu_groups/9/devices/0000:00:1c.3

2 - 网卡直通

直通网卡到虚拟机

2.1 - 设置网卡直通并检查是否生效

设置pve下的网卡直通并检查是否生效

直通网卡

创建虚拟机

特别注意,创建虚拟机时要选择 q35

在虚拟机的 hardware 设置中,添加 pci device:

注意勾选 All functions 以直通网卡上的所有网口,另外对于 pcie 设置,要勾选 “PCI-Express”。

直通两块HP544+网卡之后,虚拟机的设置如下:

2.2 - 常见问题

直通网卡的常见问题

在直通网卡时遇到很多问题,有些甚至莫名其妙,记录下来备用。

2.2.1 - missing uar aborting

直通网卡时因驱动问题造成的 missing uar aborting 错误

故障描述

网卡直通给到虚拟机后,lspci 能看到设备:

lspci | grep Mel
01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
02:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
lspci -k

可以看到网卡的驱动情况如下:

01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
	Subsystem: Hewlett-Packard Company InfiniBand FDR/Ethernet 10Gb/40Gb 2-port 544+FLR-QSFP Adapter
	Kernel driver in use: vfio-pci
	Kernel modules: mlx4_core
02:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
	Subsystem: Hewlett-Packard Company InfiniBand FDR/Ethernet 10Gb/40Gb 2-port 544+FLR-QSFP Adapter
	Kernel driver in use: vfio-pci
	Kernel modules: mlx4_core

但是直通给虚拟机之后,在虚拟机中网卡无法识别,networkctl 看不到设备:

networkctl 
IDX LINK    TYPE     OPERATIONAL SETUP     
  1 lo      loopback carrier     unmanaged 
  2 enp6s18 ether    routable    configured

2 links listed.

lsmod 时发现只有 mlx4_core , 没有其他比如 mlx4_en:

lsmod  | grep mlx
mlx4_core             311296  0

对比正常情况下的 lsmod 输出应该是这样的:

lsmod | grep mlx   
mlx4_ib               245760  0
ib_uverbs             163840  1 mlx4_ib
mlx4_en               155648  0
ib_core               393216  2 mlx4_ib,ib_uverbs
mlx4_core             405504  2 mlx4_ib,mlx4_en

查找问题

在 pve 机器中同样执行 lsmod | grep mlx 命令,会发现存在和在虚拟机中同样的问题,输出中也只有 mlx4_core:

lsmod | grep mlx   
mlx4_core             462848  0

重新安装 ubuntu server 也无法解决这个问题。而且安装 ubuntu server 20.04 时,在最开始的启动界面,会看到类似这样的错误提示:

mlx4_core 0000:01:00.0: Missing UAR, aborting

在 pve 操作系统中执行命令:

dmesg | grep mlx    

也会看到类似的输出:

[    2.364990] mlx4_core: Mellanox ConnectX core driver v4.0-0
[    2.365005] mlx4_core: Initializing 0000:01:00.0
[    2.365098] mlx4_core 0000:01:00.0: Missing UAR, aborting
[    2.365214] mlx4_core: Initializing 0000:02:00.0
[    2.365309] mlx4_core 0000:02:00.0: Missing UAR, aborting

执行命令:

dmesg | grep mlx

输出类似为:

mlx_compat: loading out-of-tree module taints kernel.[0.991286] mlx_compat: module verification failed: signature and/or required key missing - tainting kernel[0.992456] mlx4_core: Mellanox ConnectX core driver v4.1-1.0.2 (27 Jun 2017)[0.992479] mlx4_core: Initializing 0000:01:00.0[0.992621] mlx4_core 0000:01:00.0: Missing UAR, aborting

基本可以判断存在某个问题导致网卡驱动无法正确加载,从而导致网卡无法识别和驱动。

修复方式

增加 “pci=realloc=off” 参数

google之后发现有人遇到类似的问题,验证可行:

https://forums.developer.nvidia.com/t/mlx4-core-missing-uar-aborting/207322/2

按照这里的意思,应该增加 pci=realloc=off

  • edit /etc/default/grub
  • add GRUB_CMDLINE_LINUX_DEFAULT=“pci=realloc=off”
  • update-grub
  • Reboot

修改主板 bios 设置,开启 ASPM

在华硕z87-a主板,还需要在 bios 中打开 ASPM 相关的选项。

2.2.2 - IRQ冲突

直通网卡时因 IRQ 冲突造成不可用

故障描述

插入多块网卡后设置直通,在虚拟机启动时报错,错误描述如下:

kvm: -device vfio-pci,host=0000:01:00.0,id=hostpci1,bus=ich9-pcie-port-2,addr=0x0: vfio 0000:01:00.0: Failed to set up TRIGGER eventfd signaling for interrupt INTX-0: VFIO_DEVICE_SET_IRQS failure: Device or resource busy
TASK ERROR: start failed: QEMU exited with code 1

查找问题

检查 INTx disable

参考这个帖子的描述:

https://forums.unraid.net/topic/120895-passing-a-capture-card-to-vms/

可以用下面这个 check.sh 脚本来检查网卡是否设置了 INTx disable :

#!/bin/sh
# Usage $0 <PCI device>, ex: 9:00.0

INTX=$(( 0x400 ))
ORIG=$(( 0x$(setpci -s $1 4.w) ))

if [ $(( $INTX & $ORIG )) -ne 0 ]; then
echo "INTx disable supported and enabled on $1"
exit 0
fi

NEW=$(printf %04x $(( $INTX | $ORIG )))
setpci -s $1 4.w=$NEW
NEW=$(( 0x$(setpci -s $1 4.w) ))

if [ $(( $INTX & $NEW )) -ne 0 ]; then
echo "INTx disable support available on $1"
else
echo "INTx disable support NOT available on $1"
fi

NEW=$(printf %04x $ORIG)
setpci -s $1 4.w=$NEW

执行结果如下:

➜  ~ ./check.sh 01:00.0
INTx disable support available on 01:00.0
➜  ~ ./check.sh 04:00.0
INTx disable support available on 04:00.0
➜  ~ ./check.sh 08:00.0
INTx disable support available on 08:00.0
➜  ~ ./check.sh 09:00.0
INTx disable supported and enabled on 09:00.0

检查启动日志

可以执行

dmesg

查看 pve 的启动日志,找到其中报错的内容:

[ 3852.066855] vfio-pci 0000:04:00.0: vfio_ecap_init: hiding ecap 0x19@0x18c
[ 3852.210816] vfio-pci 0000:01:00.0: vfio_ecap_init: hiding ecap 0x19@0x18c
[ 3852.219438] genirq: Flags mismatch irq 16. 00000000 (vfio-intx(0000:01:00.0)) vs. 00000000 (vfio-intx(0000:04:00.0))


 3940.230432] vfio-pci 0000:04:00.0: vfio_ecap_init: hiding ecap 0x19@0x18c
[ 3940.374391] vfio-pci 0000:08:00.0: vfio_ecap_init: hiding ecap 0x19@0x18c
[ 3940.383218] genirq: Flags mismatch irq 16. 00000000 (vfio-intx(0000:08:00.0)) vs. 00000000 (vfio-intx(0000:04:00.0))

查看 IRQ 情况

IRQ 情况可以这样查看:

cat /proc/interrupts

输出为:

            CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7       CPU8       CPU9       CPU10      CPU11      
   0:         11          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC    2-edge      timer
   8:          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC    8-edge      rtc0
   9:          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC    9-fasteoi   acpi
  14:          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC   14-fasteoi   INTC1056:00
  18:          0          0          0          5          0          0          0          0          0          0          0          0  IR-IO-APIC   18-fasteoi   i801_smbus
  27:          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC   27-fasteoi   idma64.0, i2c_designware.0
  29:          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC   29-fasteoi   idma64.2, i2c_designware.2
  40:          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC   40-fasteoi   idma64.1, i2c_designware.1
 120:          0          0          0          0          0          0          0          0          0          0          0          0  DMAR-MSI    0-edge      dmar0
 121:          0          0          0          0          0          0          0          0          0          0          0          0  DMAR-MSI    1-edge      dmar1
 122:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:01.0    0-edge      PCIe PME, aerdrv
 123:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1a.0    0-edge      PCIe PME, pciehp
 124:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1b.0    0-edge      PCIe PME
 125:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1b.4    0-edge      PCIe PME, aerdrv
 126:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1c.0    0-edge      PCIe PME, pciehp
 127:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1c.1    0-edge      PCIe PME, aerdrv
 128:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1c.2    0-edge      PCIe PME, aerdrv
 129:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1c.4    0-edge      PCIe PME, aerdrv
 130:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1d.0    0-edge      PCIe PME, aerdrv
 131:          0          0      13081          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:17.0    0-edge      ahci[0000:00:17.0]
 132:          0          0          0          0    1083661          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:06:00.0    0-edge      enp6s0
 133:          0          0          0          0         90          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:14.0    0-edge      xhci_hcd
 134:          0          0          0          0          0      88674          0          0          0          0          0          0  IR-PCI-MSIX-0000:07:00.0    0-edge      enp7s0
 210:          0          0          0          0          0          0          0          0          0          0          0         74  IR-PCI-MSIX-0000:09:00.0    0-edge      mlx4-async@pci:0000:09:00.0
 211:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    1-edge      mlx4-1@0000:09:00.0
 212:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    2-edge      mlx4-2@0000:09:00.0
 213:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    3-edge      mlx4-3@0000:09:00.0
 214:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    4-edge      mlx4-4@0000:09:00.0
 215:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    5-edge      mlx4-5@0000:09:00.0
 216:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    6-edge      mlx4-6@0000:09:00.0
 217:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    7-edge      mlx4-7@0000:09:00.0
 218:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    8-edge      mlx4-8@0000:09:00.0
 219:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0    9-edge      mlx4-9@0000:09:00.0
 220:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   10-edge      mlx4-10@0000:09:00.0
 221:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   11-edge      mlx4-11@0000:09:00.0
 222:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   12-edge      mlx4-12@0000:09:00.0
 223:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   13-edge      mlx4-13@0000:09:00.0
 224:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   14-edge      mlx4-14@0000:09:00.0
 225:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   15-edge      mlx4-15@0000:09:00.0
 226:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   16-edge      mlx4-16@0000:09:00.0
 227:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   17-edge      mlx4-17@0000:09:00.0
 228:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   18-edge      mlx4-18@0000:09:00.0
 229:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   19-edge      mlx4-19@0000:09:00.0
 230:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   20-edge      mlx4-20@0000:09:00.0
 231:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   21-edge      mlx4-21@0000:09:00.0
 232:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   22-edge      mlx4-22@0000:09:00.0
 233:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   23-edge      mlx4-23@0000:09:00.0
 234:          0          0          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSIX-0000:09:00.0   24-edge      mlx4-24@0000:09:00.0
 235:          0         49          0          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:16.0    0-edge      mei_me
 236:          0          0        271          0          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:02.0    0-edge      i915
 237:          0          0          0        750          0          0          0          0          0          0          0          0  IR-PCI-MSI-0000:00:1f.3    0-edge      snd_hda_intel:card0
 NMI:          1          0          3          0          5          1          1          6          1          0          1          0   Non-maskable interrupts
 LOC:      99118      43626     176733      55708     828067     207665     115311     154475      78857      10037      61928      11351   Local timer interrupts
 SPU:          0          0          0          0          0          0          0          0          0          0          0          0   Spurious interrupts
 PMI:          1          0          3          0          5          1          1          6          1          0          1          0   Performance monitoring interrupts
 IWI:      86064      28486     141932      40754     157189      94910      89143     116144      60778       5779      51049       5784   IRQ work interrupts
 RTR:          0          0          0          0          0          0          0          0          0          0          0          0   APIC ICR read retries
 RES:        310        314       5048        112        755        544        799       3192        584         60        481         99   Rescheduling interrupts
 CAL:      20663      17009      19217      16776      19075      18387      15627      15893      17333      18026      18963      17581   Function call interrupts
 TLB:         87         35        141         33         81         26         79         62         86         18         75          8   TLB shootdowns
 TRM:          1          1          1          1          1          1          1          1          1          1          1          1   Thermal event interrupts
 THR:          0          0          0          0          0          0          0          0          0          0          0          0   Threshold APIC interrupts
 DFR:          0          0          0          0          0          0          0          0          0          0          0          0   Deferred Error APIC interrupts
 MCE:          0          0          0          0          0          0          0          0          0          0          0          0   Machine check exceptions
 MCP:         17         18         18         18         18         18         18         18         18         18         18         18   Machine check polls
 ERR:          0
 MIS:          0
 PIN:          0          0          0          0          0          0          0          0          0          0          0          0   Posted-interrupt notification event
 NPI:          0          0          0          0          0          0          0          0          0          0          0          0   Nested posted-interrupt event
 PIW:          0          0          0          0          0          0          0          0          0          0          0          0   Posted-interrupt wakeup event

对于具体的网卡,可以通过

 lspci -v -s 0000:01:00

来查看:

01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
	Subsystem: Hewlett-Packard Company InfiniBand FDR/Ethernet 10Gb/40Gb 2-port 544+FLR-QSFP Adapter
	Flags: fast devsel, IRQ 16, IOMMU group 17
	Memory at 82200000 (64-bit, non-prefetchable) [disabled] [size=1M]
	Memory at 6166000000 (64-bit, prefetchable) [disabled] [size=32M]
	Capabilities: [40] Power Management version 3
	Capabilities: [48] Vital Product Data
	Capabilities: [9c] MSI-X: Enable- Count=128 Masked-
	Capabilities: [60] Express Endpoint, MSI 00
	Capabilities: [c0] Vendor Specific Information: Len=18 <?>
	Capabilities: [100] Alternative Routing-ID Interpretation (ARI)
	Capabilities: [148] Device Serial Number c4-34-6b-ff-ff-df-e1-80
	Capabilities: [108] Single Root I/O Virtualization (SR-IOV)
	Capabilities: [154] Advanced Error Reporting
	Capabilities: [18c] Secondary PCI Express
	Kernel driver in use: vfio-pci
	Kernel modules: mlx4_core

IRQ 16,后面发现另外一个网卡(hp561万兆电口网卡)同样使用 IRQ 16 从而造成冲突。

解决方案

删除造成 irq 冲突的硬件

可以用如下方法来删除造成冲突的硬件 :

echo -n 1 > "/sys/devices/pci0000:00/0000:00:1b.0/remove"

通过 lspci 可以看到设备 device id :

lspci

00:00.0 Host bridge: Intel Corporation Device 4650 (rev 05)
00:01.0 PCI bridge: Intel Corporation 12th Gen Core Processor PCI Express x16 Controller #1 (rev 05)
00:02.0 VGA compatible controller: Intel Corporation Alder Lake-S GT1 [UHD Graphics 730] (rev 0c)
00:0a.0 Signal processing controller: Intel Corporation Platform Monitoring Technology (rev 01)
00:14.0 USB controller: Intel Corporation Alder Lake-S PCH USB 3.2 Gen 2x2 XHCI Controller (rev 11)
00:14.2 RAM memory: Intel Corporation Alder Lake-S PCH Shared SRAM (rev 11)
00:15.0 Serial bus controller: Intel Corporation Alder Lake-S PCH Serial IO I2C Controller #0 (rev 11)
00:15.1 Serial bus controller: Intel Corporation Alder Lake-S PCH Serial IO I2C Controller #1 (rev 11)
00:15.2 Serial bus controller: Intel Corporation Alder Lake-S PCH Serial IO I2C Controller #2 (rev 11)
00:16.0 Communication controller: Intel Corporation Alder Lake-S PCH HECI Controller #1 (rev 11)
00:17.0 SATA controller: Intel Corporation Alder Lake-S PCH SATA Controller [AHCI Mode] (rev 11)
00:1a.0 PCI bridge: Intel Corporation Alder Lake-S PCH PCI Express Root Port #25 (rev 11)
00:1b.0 PCI bridge: Intel Corporation Device 7ac0 (rev 11)
00:1b.4 PCI bridge: Intel Corporation Device 7ac4 (rev 11)
00:1c.0 PCI bridge: Intel Corporation Alder Lake-S PCH PCI Express Root Port #1 (rev 11)
00:1c.1 PCI bridge: Intel Corporation Alder Lake-S PCH PCI Express Root Port #2 (rev 11)
00:1c.2 PCI bridge: Intel Corporation Device 7aba (rev 11)
00:1c.4 PCI bridge: Intel Corporation Alder Lake-S PCH PCI Express Root Port #5 (rev 11)
00:1d.0 PCI bridge: Intel Corporation Alder Lake-S PCH PCI Express Root Port #9 (rev 11)
00:1f.0 ISA bridge: Intel Corporation Z690 Chipset LPC/eSPI Controller (rev 11)
00:1f.3 Audio device: Intel Corporation Alder Lake-S HD Audio Controller (rev 11)
00:1f.4 SMBus: Intel Corporation Alder Lake-S PCH SMBus Controller (rev 11)
00:1f.5 Serial bus controller: Intel Corporation Alder Lake-S PCH SPI Controller (rev 11)

01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
04:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 02)
07:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)
08:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
09:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]

尝试过,如下设置,无效:

mkdir -p /sys/devices/pci0000:00/0000:01:00.0/
mkdir -p /sys/devices/pci0000:00/0000:04:00.0/
mkdir -p /sys/devices/pci0000:00/0000:08:00.0/
mkdir -p /sys/devices/pci0000:00/0000:09:00.0/
echo -n 1 > "/sys/devices/pci0000:00/0000:01:00.0/remove"
echo -n 1 > "/sys/devices/pci0000:00/0000:04:00.0/remove"
echo -n 1 > "/sys/devices/pci0000:00/0000:08:00.0/remove"
echo -n 1 > "/sys/devices/pci0000:00/0000:09:00.0/remove"

后记

这个问题第一次在 华硕 z690-p 主板上遇到,当时插了三块 hp544+ 和一块 hp561,结果 hp561 和 hp544+ 冲突了。

后来在 z87 主板上遇到类似的问题,IRQ 冲突严重到 pve 系统都不稳定。不得已只好放弃在这两个主板上插多块网卡的想法。

3 - SR-IOV

以SR-IOV的方式直通硬件到虚拟机

3.1 - 介绍

SR-IOV介绍

介绍

SR-IOV是 “Single Root I/O Virtualization” 的缩写,是 Intel 在 2007年提出的一种基于硬件的虚拟化解决方案。

SR-IOV 规范由 PCI-SIG 在 http://www.pcisig.com 上进行定义和维护。

原理

虚拟设备有性能和时延的问题,intel VT-D ((Virtualization Technology for Directed I/O)) 可以将 PCIE 物理设备分配给虚拟机,让虚拟机直接控制硬件。

但网卡直通给虚拟机,会造成虚拟机独占网卡所在的PCIE 物理设备,就无法在其他虚拟机中使用这个设备。

为此,Intel 提出 SR-IOV ,将一个物理网卡虚拟出来多个轻量化的 PCIE 物理设备,从而可以分配给虚拟机使用。

SR-IOV 是一种规范,使得单根端口下的单个快速外围组件互连 (PCIe) 物理设备显示为管理程序或客户机操作系统的多个单独的物理设备,既有直通设备的性能优势,又可以支持多个虚拟机,一举两得。

优缺点

优点

SR-IOV 是虚拟化的一个重要功能。启用SR-IOV 将大大减轻宿主机的 CPU负荷,提高网络性能,降低网络时延等。

单个 I/O 资源可由许多虚拟机共享。共享的设备将提供专用的资源,并且还使用共享的通用资源。这样,每个虚拟机都可访问唯一的资源。因此,启用了 SR-IOV 并且具有适当的硬件和 OS 支持的 PCIe 设备(例如以太网端口)可以显示为多个单独的物理设备,每个都具有自己的 PCIe 配置空间。

  • 性能好
  • 减少主机 CPU 消耗

缺点

  • 虚拟机使用 VF 后无法进行内存超分、快照、热迁移等高级功能
  • 配置管理复杂

功能类型

SR-IOV 使用 physical functions (PF) 和 virtual functions (VF) 为 SR-IOV 设备管理全局功能。

  • PF 包含SR-IOV 功能的完整PCIe设备,PF 作为普通的PCIe 设备被发现、管理和配置 。PF 通过分配VF 来配置和管理 SR-IOV 功能。禁用SR-IOV后,主机将在一个物理网卡上创建一个 PF。
  • VF 是轻量级 PCIe 功能(I/O 处理)的 PCIe 设备,每个 VF 都是通过 PF 来生成管理的,VF 的具体数量限制受限于 PCIe 设备自身配置及驱动程序的支持,启用SR-IOV后,主机将在一个物理NIC上创建单个PF和多个VF。 VF的数量取决于配置和驱动程序支持。

每个 SR-IOV 设备都可有一个 PF(Physical Functions),并且每个 PF 最多可有64,000个与其关联的 VF(Virtual Function)。PF 可以通过寄存器创建 VF,这些寄存器设计有专用于此目的的属性。一旦在 PF 中启用了 SR-IOV,就可以通过 PF 的总线、设备和功能编号(路由 ID)访问各个 VF 的 PCI 配置空间。

每个 VF 都具有一个 PCI 内存空间,用于映射其寄存器集。VF设备驱动程序对寄存器集进行操作以启用其功能,并且显示为实际存在的PCI设备。创建 VF 后,可以直接将其指定给虚拟机或各个应用程序。此功能使得虚拟功能可以共享物理设备,并在没有CPU和虚拟机管理程序软件开销的情况下执行 I/O。

通过下面的命令查看开启 sriov 的 pci 设备,一块设置了 8 个 VF的 ConnectX-3 Pro 网卡:

lspci -vvv | grep Mellanox

输出为:

81:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
81:00.1 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.2 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.3 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.4 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.5 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.6 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.7 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:01.0 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]

参考资料

3.2 - 配置 CX-3 网卡以开启 SR-IOV

配置 Mellanox connextx-3 网卡配置以便在 pve 中开启网卡的 SR-IOV 功能

准备工作

更新网卡固件

对于 HP544+ 网卡,参考:

https://skyao.io/learning-computer-hardware/nic/hp544/firmware/

设置主板bios

需要在主板中设置开启以下功能:

  • 虚拟机支持
  • vt-d
  • SR-IOV

安装 pve-headers

对于 PVE,还需要安装额外的 pve-headers,否则后续安装 mft 时会报错,提示要安装 linux-headers 和 linux-headers-generic:

./install.sh
-E- There are missing packages that are required for installation of MFT.
-I- You can install missing packages using: apt-get install linux-headers linux-headers-generic

安装:

apt install -y gcc make dkms
apt install -y pve-headers-$(uname -r)
apt install --fix-broken

安装完成之后,需要重启,否则直接安装 mft,依然会继续同样报错。

安装 mft

需要 mft 工具修改 ConnectX 网卡的配置,对于 cx3 pro (hp544+)网卡下载安装方式为:

mkdir -p ~/work/soft/mellanox
cd ~/work/soft/mellanox

wget --no-check-certificate https://www.mellanox.com/downloads/MFT/mft-4.24.0-72-x86_64-deb.tgz
tar xvf mft-4.24.0-72-x86_64-deb.tgz
cd mft-4.24.0-72-x86_64-deb

对于 cx4 / cx5 等新一点的网卡,可以安装 mft 最新版本。

wget --no-check-certificate https://www.mellanox.com/downloads/MFT/mft-4.27.0-83-x86_64-deb.tgz
tar xvf mft-4.27.0-83-x86_64-deb.tgz
cd mft-4.27.0-83-x86_64-deb

执行安装脚本:

./install.sh

输出为:

-I- Removing mft external packages installed on the machine
-I- Installing package: /root/temp/mft-4.24.0-72-x86_64-deb/SDEBS/kernel-mft-dkms_4.24.0-72_all.deb
-I- Installing package: /root/temp/mft-4.24.0-72-x86_64-deb/DEBS/mft_4.24.0-72_amd64.deb
-I- In order to start mst, please run "mst start".

下载 mlxup

cd ~/work/soft/mellanox

wget https://www.mellanox.com/downloads/firmware/mlxup/4.22.1/SFX/linux_x64/mlxup
chmod +x ./mlxup
./mlxup

能看到当前网卡的固件情况:

Querying Mellanox devices firmware ...

Device #1:
----------

  Device Type:      ConnectX3Pro
  Part Number:      764285-B21_Ax
  Description:      HP InfiniBand FDR/Ethernet 10Gb/40Gb 2-port 544+FLR-QSFP Adapter
  PSID:             HP_1380110017
  PCI Device Name:  /dev/mst/mt4103_pci_cr0
  Port1 GUID:       c4346bffffdfe181
  Port2 GUID:       c4346bffffdfe182
  Versions:         Current        Available     
     FW             2.42.5700      N/A           

  Status:           No matching image found

安装 mstflint

apt install mstflint

设置网卡

启动 mft 工具

mst start

输入为:

Starting MST (Mellanox Software Tools) driver set
Loading MST PCI module - Success
Loading MST PCI configuration module - Success
Create devices

查看网卡配置

mst status

可以看到当前网卡信息(这是只插了一块HP544+ 网卡的情况):

MST modules:
------------
    MST PCI module loaded
    MST PCI configuration module loaded

MST devices:
------------
/dev/mst/mt4103_pciconf0         - PCI configuration cycles access.
                                   domain:bus:dev.fn=0000:02:00.0 addr.reg=88 data.reg=92 cr_bar.gw_offset=-1
                                   Chip revision is: 00
/dev/mst/mt4103_pci_cr0          - PCI direct access.
                                   domain:bus:dev.fn=0000:02:00.0 bar=0xdfe00000 size=0x100000
                                   Chip revision is: 00

继续执行命令:

mlxconfig -d /dev/mst/mt4103_pciconf0 q

可以看到网卡的配置信息:

Device #1:
----------

Device type:    ConnectX3Pro    
Device:         /dev/mst/mt4103_pciconf0

Configurations:                                      Next Boot
         SRIOV_EN                                    True(1)         
         NUM_OF_VFS                                  16              
         WOL_MAGIC_EN_P2                             True(1)         
         LINK_TYPE_P1                                VPI(3)          
         PHY_TYPE_P1                                 0               
         XFI_MODE_P1                                 _10G(0)         
         FORCE_MODE_P1                               False(0)        
         LINK_TYPE_P2                                VPI(3)          
         PHY_TYPE_P2                                 0               
         XFI_MODE_P2                                 _10G(0)     

修改网卡配置

mlxconfig -d /dev/mst/mt4103_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=8

对于有多块网卡的机器,可以根据需要决定是否为其中的一块或者多块网卡开启 SR-IOV ,然后需要开启的设置 SRIOV_EN=1 ,不需要开启的设置 SRIOV_EN=0。

注意这里的 mt4103_pciconf0 / mt4103_pciconf1 等编号是按照 lspci 时显示的设备 id 来排序的,因此用这个方法可以分辨各个网卡。

重启机器。

设置网卡驱动

vi /etc/modprobe.d/mlx4_core.conf

对于 hp544+ 网卡,输入内容为(在双头网卡上配置8个VF, 都在端口1上生效):

options mlx4_core port_type_array=2,2 num_vfs=8,0,0 probe_vf=8,0,0 log_num_mgm_entry_size=-1
options mlx4_core enable_sys_tune=1
options mlx4_en inline_thold=0

执行:

update-initramfs -u

开启 SR-IOV

开启成功时的例子,这里有两块网卡,一块设置开启 SR-IOV,另一块设置不开启 SR-IOV (准备网卡整体直通给虚拟机)。

lspci | grep Mel
01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
04:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
04:00.1 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.2 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.3 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.4 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.5 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.6 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.7 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:01.0 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
  • 01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro] : 设置为不开启 SR-IOV 的网卡,显示为一块物理网卡(PF)。
  • 04:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]: 设置为开启 SR-IOV 的网卡,显示为一块物理网卡(PF) + 下面多块(例子中是每个port 4个,一共8个) 虚拟网卡(VF)。
  • 04:00.x Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]: 设置为开启 SR-IOV 的网卡的所有的 VF 。

参考资料

3.3 - 配置 CX-4 网卡以开启 SR-IOV

配置 Mellanox connextx-4 网卡配置以便在 pve 中开启网卡的 SR-IOV 功能

准备工作

更新网卡固件

对于 mcx4121 网卡,参考:

https://skyao.io/learning-computer-hardware/nic/cx4121a/firmware/

设置主板bios

需要在主板中设置开启以下功能:

  • 虚拟机支持
  • vt-d
  • SR-IOV

安装 pve-headers

对于 PVE,还需要安装额外的 pve-headers,否则后续安装 mft 时会报错,提示要安装 linux-headers 和 linux-headers-generic:

./install.sh
-E- There are missing packages that are required for installation of MFT.
-I- You can install missing packages using: apt-get install linux-headers linux-headers-generic

安装:

apt install -y gcc make dkms
apt install -y pve-headers-$(uname -r)
apt install --fix-broken

安装完成之后,需要重启,否则直接安装 mft,依然会继续同样报错。

安装 mft

对于 cx4 / cx5 等新一点的网卡,可以安装 mft 最新版本。

mkdir -p ~/work/soft/mellanox
cd ~/work/soft/mellanox

wget --no-check-certificate https://www.mellanox.com/downloads/MFT/mft-4.27.0-83-x86_64-deb.tgz
tar xvf mft-4.27.0-83-x86_64-deb.tgz
cd mft-4.27.0-83-x86_64-deb

执行安装脚本:

./install.sh

输出为:

-I- Removing mft external packages installed on the machine
-I- Removing the packages:  kernel-mft-dkms...
-I- Installing package: /root/temp/mft-4.27.0-83-x86_64-deb/SDEBS/kernel-mft-dkms_4.27.0-83_all.deb
-I- Installing package: /root/temp/mft-4.27.0-83-x86_64-deb/DEBS/mft_4.27.0-83_amd64.deb
-I- Installing package: /root/temp/mft-4.27.0-83-x86_64-deb/DEBS/mft-autocomplete_4.27.0-83_amd64.deb

下载 mlxup

cd ~/work/soft/mellanox

wget https://www.mellanox.com/downloads/firmware/mlxup/4.22.1/SFX/linux_x64/mlxup
chmod +x ./mlxup
./mlxup

能看到当前网卡的固件情况:

Querying Mellanox devices firmware ...

Device #1:
----------

  Device Type:      ConnectX3Pro
  Part Number:      764285-B21_Ax
  Description:      HP InfiniBand FDR/Ethernet 10Gb/40Gb 2-port 544+FLR-QSFP Adapter
  PSID:             HP_1380110017
  PCI Device Name:  /dev/mst/mt4103_pci_cr0
  Port1 GUID:       c4346bffffdfe181
  Port2 GUID:       c4346bffffdfe182
  Versions:         Current        Available     
     FW             2.42.5700      N/A           

  Status:           No matching image found

安装 mstflint

apt install mstflint

设置网卡

启动 mft 工具

mst start

输出为:

Starting MST (Mellanox Software Tools) driver set
Loading MST PCI module - Success
Loading MST PCI configuration module - Success
Create devices
Unloading MST PCI module (unused) - Success

查看网卡配置

mst status

可以看到当前网卡信息(这是只插了一块 mcx4121a 网卡的情况):

MST modules:
------------
    MST PCI module is not loaded
    MST PCI configuration module loaded

MST devices:
------------
/dev/mst/mt4117_pciconf0         - PCI configuration cycles access.
                                   domain:bus:dev.fn=0000:06:00.0 addr.reg=88 data.reg=92 cr_bar.gw_offset=-1
                                   Chip revision is: 00

继续执行命令:

mlxconfig -d /dev/mst/mt4117_pciconf0 q

可以看到网卡的配置信息:

Device #1:
----------

Device type:        ConnectX4LX         
Name:               MCX4121A-ACU_Ax     
Description:        ConnectX-4 Lx EN network interface card; 25GbE dual-port SFP28; PCIe3.0 x8; UEFI Enabled; tall bracket
Device:             /dev/mst/mt4117_pciconf0

Configurations:                                          Next Boot
        MEMIC_BAR_SIZE                              0                   
        MEMIC_SIZE_LIMIT                            _256KB(1)           
        FLEX_PARSER_PROFILE_ENABLE                  0                   
        FLEX_IPV4_OVER_VXLAN_PORT                   0                   
        ROCE_NEXT_PROTOCOL                          254                 
        PF_NUM_OF_VF_VALID                          False(0)            
        NON_PREFETCHABLE_PF_BAR                     False(0)            
        VF_VPD_ENABLE                               False(0)            
        STRICT_VF_MSIX_NUM                          False(0)            
        VF_NODNIC_ENABLE                            False(0)            
        NUM_PF_MSIX_VALID                           True(1)             
        NUM_OF_VFS                                  8                   
        NUM_OF_PF                                   2                   
        SRIOV_EN                                    True(1)             
        PF_LOG_BAR_SIZE                             5                   
        VF_LOG_BAR_SIZE                             0                   
        NUM_PF_MSIX                                 63                  
        NUM_VF_MSIX                                 11                  
        INT_LOG_MAX_PAYLOAD_SIZE                    AUTOMATIC(0)        
        PCIE_CREDIT_TOKEN_TIMEOUT                   0                   
        ACCURATE_TX_SCHEDULER                       False(0)            
        PARTIAL_RESET_EN                            False(0)            
        SW_RECOVERY_ON_ERRORS                       False(0)            
        RESET_WITH_HOST_ON_ERRORS                   False(0)            
        PCI_BUS0_RESTRICT_SPEED                     PCI_GEN_1(0)        
        PCI_BUS0_RESTRICT_ASPM                      False(0)            
        PCI_BUS0_RESTRICT_WIDTH                     PCI_X1(0)           
        PCI_BUS0_RESTRICT                           False(0)            
        PCI_DOWNSTREAM_PORT_OWNER                   Array[0..15]        
        CQE_COMPRESSION                             BALANCED(0)         
        IP_OVER_VXLAN_EN                            False(0)            
        MKEY_BY_NAME                                False(0)            
        UCTX_EN                                     True(1)             
        PCI_ATOMIC_MODE                             PCI_ATOMIC_DISABLED_EXT_ATOMIC_ENABLED(0)
        TUNNEL_ECN_COPY_DISABLE                     False(0)            
        LRO_LOG_TIMEOUT0                            6                   
        LRO_LOG_TIMEOUT1                            7                   
        LRO_LOG_TIMEOUT2                            8                   
        LRO_LOG_TIMEOUT3                            13                  
        ICM_CACHE_MODE                              DEVICE_DEFAULT(0)   
        TX_SCHEDULER_BURST                          0                   
        LOG_MAX_QUEUE                               17                  
        LOG_DCR_HASH_TABLE_SIZE                     14                  
        MAX_PACKET_LIFETIME                         0                   
        DCR_LIFO_SIZE                               16384               
        ROCE_CC_PRIO_MASK_P1                        255                 
        ROCE_CC_PRIO_MASK_P2                        255                 
        CLAMP_TGT_RATE_AFTER_TIME_INC_P1            True(1)             
        CLAMP_TGT_RATE_P1                           False(0)            
        RPG_TIME_RESET_P1                           300                 
        RPG_BYTE_RESET_P1                           32767               
        RPG_THRESHOLD_P1                            1                   
        RPG_MAX_RATE_P1                             0                   
        RPG_AI_RATE_P1                              5                   
        RPG_HAI_RATE_P1                             50                  
        RPG_GD_P1                                   11                  
        RPG_MIN_DEC_FAC_P1                          50                  
        RPG_MIN_RATE_P1                             1                   
        RATE_TO_SET_ON_FIRST_CNP_P1                 0                   
        DCE_TCP_G_P1                                1019                
        DCE_TCP_RTT_P1                              1                   
        RATE_REDUCE_MONITOR_PERIOD_P1               4                   
        INITIAL_ALPHA_VALUE_P1                      1023                
        MIN_TIME_BETWEEN_CNPS_P1                    4                   
        CNP_802P_PRIO_P1                            6                   
        CNP_DSCP_P1                                 48                  
        CLAMP_TGT_RATE_AFTER_TIME_INC_P2            True(1)             
        CLAMP_TGT_RATE_P2                           False(0)            
        RPG_TIME_RESET_P2                           300                 
        RPG_BYTE_RESET_P2                           32767               
        RPG_THRESHOLD_P2                            1                   
        RPG_MAX_RATE_P2                             0                   
        RPG_AI_RATE_P2                              5                   
        RPG_HAI_RATE_P2                             50                  
        RPG_GD_P2                                   11                  
        RPG_MIN_DEC_FAC_P2                          50                  
        RPG_MIN_RATE_P2                             1                   
        RATE_TO_SET_ON_FIRST_CNP_P2                 0                   
        DCE_TCP_G_P2                                1019                
        DCE_TCP_RTT_P2                              1                   
        RATE_REDUCE_MONITOR_PERIOD_P2               4                   
        INITIAL_ALPHA_VALUE_P2                      1023                
        MIN_TIME_BETWEEN_CNPS_P2                    4                   
        CNP_802P_PRIO_P2                            6                   
        CNP_DSCP_P2                                 48                  
        LLDP_NB_DCBX_P1                             False(0)            
        LLDP_NB_RX_MODE_P1                          OFF(0)              
        LLDP_NB_TX_MODE_P1                          OFF(0)              
        LLDP_NB_DCBX_P2                             False(0)            
        LLDP_NB_RX_MODE_P2                          OFF(0)              
        LLDP_NB_TX_MODE_P2                          OFF(0)              
        ROCE_RTT_RESP_DSCP_P1                       0                   
        ROCE_RTT_RESP_DSCP_MODE_P1                  DEVICE_DEFAULT(0)   
        ROCE_RTT_RESP_DSCP_P2                       0                   
        ROCE_RTT_RESP_DSCP_MODE_P2                  DEVICE_DEFAULT(0)   
        DCBX_IEEE_P1                                True(1)             
        DCBX_CEE_P1                                 True(1)             
        DCBX_WILLING_P1                             True(1)             
        DCBX_IEEE_P2                                True(1)             
        DCBX_CEE_P2                                 True(1)             
        DCBX_WILLING_P2                             True(1)             
        KEEP_ETH_LINK_UP_P1                         True(1)             
        KEEP_IB_LINK_UP_P1                          False(0)            
        KEEP_LINK_UP_ON_BOOT_P1                     False(0)            
        KEEP_LINK_UP_ON_STANDBY_P1                  False(0)            
        DO_NOT_CLEAR_PORT_STATS_P1                  False(0)            
        AUTO_POWER_SAVE_LINK_DOWN_P1                False(0)            
        KEEP_ETH_LINK_UP_P2                         True(1)             
        KEEP_IB_LINK_UP_P2                          False(0)            
        KEEP_LINK_UP_ON_BOOT_P2                     False(0)            
        KEEP_LINK_UP_ON_STANDBY_P2                  False(0)            
        DO_NOT_CLEAR_PORT_STATS_P2                  False(0)            
        AUTO_POWER_SAVE_LINK_DOWN_P2                False(0)            
        NUM_OF_VL_P1                                _4_VLs(3)           
        NUM_OF_TC_P1                                _8_TCs(0)           
        NUM_OF_PFC_P1                               8                   
        VL15_BUFFER_SIZE_P1                         0                   
        NUM_OF_VL_P2                                _4_VLs(3)           
        NUM_OF_TC_P2                                _8_TCs(0)           
        NUM_OF_PFC_P2                               8                   
        VL15_BUFFER_SIZE_P2                         0                   
        DUP_MAC_ACTION_P1                           LAST_CFG(0)         
        SRIOV_IB_ROUTING_MODE_P1                    LID(1)              
        IB_ROUTING_MODE_P1                          LID(1)              
        DUP_MAC_ACTION_P2                           LAST_CFG(0)         
        SRIOV_IB_ROUTING_MODE_P2                    LID(1)              
        IB_ROUTING_MODE_P2                          LID(1)              
        PHY_FEC_OVERRIDE_P1                         DEVICE_DEFAULT(0)   
        PHY_FEC_OVERRIDE_P2                         DEVICE_DEFAULT(0)   
        PF_SD_GROUP                                 0                   
        ROCE_CONTROL                                ROCE_ENABLE(2)      
        PCI_WR_ORDERING                             per_mkey(0)         
        MULTI_PORT_VHCA_EN                          False(0)            
        PORT_OWNER                                  True(1)             
        ALLOW_RD_COUNTERS                           True(1)             
        RENEG_ON_CHANGE                             True(1)             
        TRACER_ENABLE                               True(1)             
        IP_VER                                      IPv4(0)             
        BOOT_UNDI_NETWORK_WAIT                      0                   
        UEFI_HII_EN                                 True(1)             
        BOOT_DBG_LOG                                False(0)            
        UEFI_LOGS                                   DISABLED(0)         
        BOOT_VLAN                                   1                   
        LEGACY_BOOT_PROTOCOL                        PXE(1)              
        BOOT_INTERRUPT_DIS                          False(0)            
        BOOT_LACP_DIS                               True(1)             
        BOOT_VLAN_EN                                False(0)            
        BOOT_PKEY                                   0                   
        DYNAMIC_VF_MSIX_TABLE                       False(0)            
        ADVANCED_PCI_SETTINGS                       False(0)            
        SAFE_MODE_THRESHOLD                         10                  
        SAFE_MODE_ENABLE                            True(1)

修改网卡配置

mlxconfig -d /dev/mst/mt4117_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=8

对于有多块网卡的机器,可以根据需要决定是否为其中的一块或者多块网卡开启 SR-IOV ,然后需要开启的设置 SRIOV_EN=1 ,不需要开启的设置 SRIOV_EN=0。

重启机器。

开启 SR-IOV

开启前的检查

查看网卡情况:

ip addr

enp6s0f0np0 和 enp6s0f1np1 为这块 cx4 lx 双头网卡的两个网口,这里我们使用了 enp6s0f1np1:

2: enp6s0f0np0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether b8:ce:f6:0b:d9:1c brd ff:ff:ff:ff:ff:ff
3: enp6s0f1np1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master vmbr0 state UP group default qlen 1000
    link/ether b8:ce:f6:0b:d9:1d brd ff:ff:ff:ff:ff:ff

查看网卡 pci 情况:

lspci -k | grep -i ethernet

可以看到 enp6s0f1np1 这个网卡对应的是 06:00.1 :

06:00.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
06:00.1 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]

执行命令查看网卡的 vfs 设置:

cat /sys/bus/pci/devices/0000:06:00.1/sriov_totalvfs
8

开启的脚本

新建文件 cx4sriov.service:

cd /etc/systemd/system
vi cx4sriov.service

内容为(注意替换 enp6s0f1np1):

[Unit]
Description=Script to enable SR-IOV for cx4 NIC on boot

[Service]
Type=simple

start SR-IOV

ExecStartPre=/usr/bin/bash -c '/usr/bin/echo 8 > /sys/class/net/enp6s0f1np1/device/sriov_numvfs'

set VF MAC

ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 0 mac 00:80:00:00:00:00'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 1 mac 00:80:00:00:00:01'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 2 mac 00:80:00:00:00:02'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 3 mac 00:80:00:00:00:03'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 4 mac 00:80:00:00:00:04'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 5 mac 00:80:00:00:00:05'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 6 mac 00:80:00:00:00:06'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp6s0f1np1 vf 7 mac 00:80:00:00:00:07'

set PF up

ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1 up'

set VF up

ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v0 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v1 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v2 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v3 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v4 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v5 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v6 up'
ExecStart=/usr/bin/bash -c '/usr/bin/ip link set enp6s0f1np1v7 up'

Restart=on-failure

[Install]
WantedBy=multi-user.target

启用 cx4sriov.service:

systemctl daemon-reload
systemctl enable cx4sriov.service
reboot

重启之后查看网卡信息:

$ lspci -k | grep -i ethernet

06:00.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
06:00.1 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
06:01.2 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
06:01.3 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
06:01.4 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
06:01.5 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
06:01.6 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
06:01.7 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
06:02.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
06:02.1 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function]
$ ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enp6s0f0np0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether b8:ce:f6:0b:d9:1c brd ff:ff:ff:ff:ff:ff
3: enp6s0f1np1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master vmbr0 state UP group default qlen 1000
    link/ether b8:ce:f6:0b:d9:1d brd ff:ff:ff:ff:ff:ff
4: vmbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether b8:ce:f6:0b:d9:1d brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.109/24 scope global vmbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::bace:f6ff:fe0b:d91d/64 scope link 
       valid_lft forever preferred_lft forever
5: enp6s0f1v0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether ae:0a:fe:86:e3:9a brd ff:ff:ff:ff:ff:ff
6: enp6s0f1v1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 12:e3:9e:f9:22:b6 brd ff:ff:ff:ff:ff:ff
7: enp6s0f1v2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 2a:f5:00:14:0f:cc brd ff:ff:ff:ff:ff:ff
8: enp6s0f1v3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether ba:5d:6c:3d:4a:68 brd ff:ff:ff:ff:ff:ff
9: enp6s0f1v4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 86:e2:c0:ec:a3:d8 brd ff:ff:ff:ff:ff:ff
10: enp6s0f1v5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether aa:52:93:a7:01:af brd ff:ff:ff:ff:ff:ff
11: enp6s0f1v6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether be:b2:59:79:13:9f brd ff:ff:ff:ff:ff:ff
12: enp6s0f1v7: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 3a:07:60:b5:04:74 brd ff:ff:ff:ff:ff:ff

参考资料

3.4 - 为不同端口分别配置VF

在 pve 下为不同端口分别配置 SR-IOV 的 VF

背景

之前的 sr-iov 配置,对于有两个 port (即双头网卡)的网卡是以相同方式进行配置的,这样产生的 vf 对应到不同的端口。

options mlx4_core num_vfs=4,4,0 port_type_array=2,2 probe_vf=4,4,0 probe_vf=4,4,0

有些,我们需要对不同的端口进行不一样的配置,比如可能只使用其中的一个端口,或者某一个端口可能就不使用 vf 了。

配置方式

参考文章 HOWTO CONFIGURE SR-IOV VFS ON DIFFERENT CONNECTX-3 PORTS

为单头网卡配置8个 VF

编辑 /etc/modprobe.d/mlx4.conf ,设置

options mlx4_core port_type_array=2 num_vfs=8 probe_vf=8 log_num_mgm_entry_size=-1

在双头网卡上配置8个VF, 都在端口1上生效

options mlx4_core port_type_array=2,2 num_vfs=8,0,0 probe_vf=8,0,0 log_num_mgm_entry_size=-1

在双头网卡上配置8个VF, 4个VF在端口1上生效,4个VF在端口2上生效

options mlx4_core port_type_array=2,2 num_vfs=4,4,0 probe_vf=4,4,0 log_num_mgm_entry_size=-1

在双头网卡上配置8个VF, 2个VF在端口1上生效,2个VF在端口2上生效,还有4个VF在两个端口上都生效

options mlx4_core port_type_array=2,2 num_vfs=2,2,4 probe_vf=2,2,4 log_num_mgm_entry_size=-1

参考资料

3.5 - 开启 SR-IOV 时的常见问题

在 pve 中开启网卡 SR-IOV 功能常遇见的问题

3.5.1 - 不支持开启 SR-IOV

在 pve 中遇到的不支持开启 SR-IOV 的情况

技嘉x99 ud4 主板没有 SR-IOV 设置项

这个主板非常奇怪,bios 选项中找不到 SR-IOV 的设置项,当然,虚拟化支持和 vt-x 是可以的。

后来意外发现:只有在清理 cmos 后第一次启动进入 bios 时,能够在网卡列表中看到当前的所有网卡,其中包括我的 hp544+ 和 realtek 8125b。这是可以进入网卡的配置中找到 SR-IOv 的支持选项,默认是开启的。

但奇怪的是,只要保存 bios,之后再次进入 bios, 就会发现再也无法列出 hp544+ 网卡 , 而 realtek 8125b 网卡有时候有,有没有没有。也就是说只有清理 bios 之后的第一次进入bios能看到网卡列表。反复测试过几次都是这样,不清楚问题所在。

尝试过清理bios后,第一次进入,就把所有的配置都设置好,保存,启动机器,然后再试开启 SR-IOV。这是寄希望于虽然网卡列表不显示但第一次配置的信息还能生效,但很遗憾的失败了。

开启 SR-IOV 导致启动时报错:

[   13.741520] mlx4_core 0000:02:00.0: DMFS high rate steer mode is: performance optimized for limited rule configuration (static)
[   13.741725] mlx4_core 0000:02:00.0: Enabling SR-IOV with 8 VFs
[   13.741741] mlx4_core 0000:02:00.0: not enough MMIO resources for SR-IOV
[   13.741747] mlx4_core 0000:02:00.0: Failed to enable SR-IOV, continuing without SR-IOV (err = -12)

最后,无奈的放弃了在 技嘉x99 ud4 主板上开启 SR-IOV 的尝试,最终选择了性能最佳毛病最少的物理机方案(虚拟机直通方案遇到 IRQ 冲突)。

4 - SR-IOV实战

SR-IOV 实战的例子

4.1 - 带管理网络的 SR-IOV 实战

在开启 SR-IOV 给虚拟机共享网卡的同时支持管理网络

背景

需求:

  • 在 pve 的各个虚拟机中分享网卡
  • 同时支持管理网络也使用这个网卡, 从而实现管理网络的高速通讯

设备:

  • 一块 40G/56G 网卡,型号为 HP544+,双口(但当前实战中只使用到一个口)

目标:

  • 虚拟机中可以自由使用该网卡实现高速通讯
  • 管理网络也使用这个网卡

规划:

  • HP544+ 网卡
  • 开启 SR-IOV
  • PF 用于 vmbr0 实现管理网络
  • VF 直通给到虚拟机

实现步骤:

  1. 先安装 PVE, 使用 HP544+ 网卡做管理网络,vmbr0 会基于 HP544+ 网卡
  2. 开启直通,设置 HP544+ 网卡 的 SR-IOV 配置
  3. 配置 ubuntu server 虚拟机,直通 VF
  4. 在 ubuntu server 虚拟机中检验网卡的使用

准备工作

安装 PVE

正常安装 PVE, 安装时网卡选择 HP544+ 网卡,填写网络信息类似为:

  • ip 地址: 192.168.99.18
  • 网关:192.168.99.1
  • DNS: 192.168.99.1

PVE 安装完成后,检查是否可以连接到网关

ping 192.168.99.1

如果有问题,则需要

ip addr

查看网卡情况,然后执行

vi /etc/network/interfaces

修改 vmbr0 的配置,指向正确的网卡。然后执行

ifup -a

让网卡配置生效。重新 ping 来检验连接是否成功。

安装网卡相关软件

需要安装以下工具软件:

  • mft 工具
  • mlxup
  • mstflint

实战步骤

开启直通

按照前面介绍的方式,开启 pve 的直通支持。

设置 SR-IOV

修改 HP544+ 网卡配置:

mst start

mlxconfig -d /dev/mst/mt4103_pci_cr0 reset

mlxconfig -d /dev/mst/mt4103_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=8 WOL_MAGIC_EN_P2=0 LINK_TYPE_P1=2 LINK_TYPE_P2=2

然后执行

vi /etc/modprobe.d/mlx4_core.conf

修改网卡配置为只在 port 1 上建立8个 vf:

options mlx4_core port_type_array=2,2 num_vfs=8,0,0 probe_vf=8,0,0 log_num_mgm_entry_size=-1

最后执行

update-initramfs -u

重启机器。

此时 ip addr 看到的是:

4: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master vmbr0 state UP group default qlen 1000
    link/ether 48:0f:cf:ef:08:11 brd ff:ff:ff:ff:ff:ff
    altname enp129s0
5: ens4d1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 48:0f:cf:ef:08:12 brd ff:ff:ff:ff:ff:ff
    altname enp129s0d1
6: ens4v0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 7e:e8:bb:78:9b:e4 brd ff:ff:ff:ff:ff:ff
    altname enp129s0v0
7: ens4v1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 52:59:cf:53:10:ac brd ff:ff:ff:ff:ff:ff
    altname enp129s0v1
8: ens4v2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 02:d6:04:5b:7e:63 brd ff:ff:ff:ff:ff:ff
    altname enp129s0v2
9: ens4v3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether ee:89:43:2e:af:d3 brd ff:ff:ff:ff:ff:ff
    altname enp129s0v3
10: ens4v4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 8e:8d:ac:50:63:17 brd ff:ff:ff:ff:ff:ff
    altname enp129s0v4
11: ens4v5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 7e:b7:b5:c7:2a:bf brd ff:ff:ff:ff:ff:ff
    altname enp129s0v5
12: ens4v6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 76:47:57:f5:b7:c8 brd ff:ff:ff:ff:ff:ff
    altname enp129s0v6
13: ens4v7: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 3e:10:37:3c:86:49 brd ff:ff:ff:ff:ff:ff
    altname enp129s0v7
14: ens4v8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 76:34:75:33:95:6b brd ff:ff:ff:ff:ff:ff
    altname enp129s0v8
15: ens4v9: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether ee:13:54:87:51:bc brd ff:ff:ff:ff:ff:ff
    altname enp129s0v9
16: ens4v10: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 5a:33:72:74:5a:78 brd ff:ff:ff:ff:ff:ff
    altname enp129s0v10
17: ens4v11: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether ae:a4:58:ec:ee:0a brd ff:ff:ff:ff:ff:ff
    altname enp129s0v11
18: vmbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 48:0f:cf:ef:08:11 brd ff:ff:ff:ff:ff:ff
    inet 192.168.99.58/24 scope global vmbr0
       valid_lft forever preferred_lft forever

执行

lspci | grep Mel

可以看到

81:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
81:00.1 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.2 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.3 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.4 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.5 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.6 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:00.7 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:01.0 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:01.1 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:01.2 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:01.3 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
81:01.4 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]

速度对比

虚拟机使用 vmbr0

iperf -c 192.168.99.1 -P 10 -t 20 -i 1

实际测试下来大概是 20G:

[SUM]  0.0-20.1 sec  46.8 GBytes  20.0 Gbits/sec

虚拟机使用 VF

直通一个 VF 进入虚拟机,删除 vmbr0, 同样测速,结果大概是 42.8 G:

[SUM]  0.0-20.0 sec  99.8 GBytes  42.8 Gbits/sec

虚拟机直通网卡

这个之前测试过,速度可以达到 48G ,基本等同于物理机上测试的结果。

总结

以 HP544+ 网卡为例,开启 56G eth 模式,各种情况下的 iperf 测试结果是这样的:

  1. 物理机下速度最快: 48G,得益于 rdma, CPU 占用基本为零
  2. 虚拟机网卡直通基本等同于物理机:同样 48g 速度 + CPU 占用基本为零
  3. PVE 系统直接使用 vmbr, 接近物理机和直通(算九五折): 45到47.9g不等,cpu占用约 20%
  4. 开启 SR-IOV 直通 VF, 速度下降:大约 42.8 g, 和最高性能相比打八折
  5. 虚拟机使用vmbr:速度最慢,约 20G, 和最高性能相比打四折,而且 cpu 占用很高

所以,建议在不同场景下酌情使用:

  • vmbr 方法:最灵活,但性能最低(打四折),适用于无法或者不方便开启直通/SR-IOV 的场合
  • 直通方案:性能最高,直逼物理机,但有独占网卡的限制
  • SR-IOV 直通 VF 方案:兼顾性能和灵活度,八折性能换来可以在多个虚拟机中共享网卡 (HP544+ 网卡最多可以有 15 个 VF)

4.2 - 软路由+软交换实战

基于openwrt+ubuntu server的软路由+软交换实战

背景

需求:

  • 在 pve 中搭建 openwrt 的虚拟机,实现软路由功能
  • 在 pve 中搭建 ubuntu server 的虚拟机,实现软交换功能

设备:

  • 两块 2.5G 网卡,型号为 realtek 8125b,单口
  • 两块 40G 网卡,型号为 HP544+,双口

目标:

  • openwrt 能实现拨号上网的功能
  • openwrt 能提供 DHCP 服务
  • 40G 网卡能组建一个高速子网(这是下一个实战的内容),并且开启 RDMA 功能以保证速度和性能
  • pve 机器上的其他虚拟机可以自如的访问 40g 和 2.5G 网络

规划:

  • 两块 2.5g 网卡,分别用于 openwrt 的 wan 和 lan

    • 其中 lan 会接入 2.5G 交换机,为内网其他设备提供网络服务
    • wan 接入 2.5G 光猫,实现拨号上网
  • 两块 40G 网卡

    • 一块 40G 网卡 将完全直通给到 ubuntu server 虚拟机,提供两个速度和性能最佳的网口给到下游设备
    • 一块 40G 网卡将开启 SR-IOV,
      • port1 的PF(物理网卡)将以 vmbr 的形式提供 PVE 管理网络
      • port1 和 port2 的第一个 VF 将直通给到 ubuntu server 虚拟机,提供两个速度和性能还不错(比完整直通低,比网桥高)的网口给到下游设备

实现步骤:

  1. 先在现有网络中安装 pve 到物理机,实现现有网络作为 pve 的管理网络
  2. 安装 openwrt 虚拟机和 ubuntu server 虚拟机
  3. 开启 SR-IOV 和 直通,准备必要的 vmbr,然后分别分配给 openwrt 虚拟机和 ubuntu server 虚拟机
  4. 配置 openwrt 虚拟机,实现 wan (使用临时网段暂时先接入现有网络)和 lan, DHCP 分配
  5. 配置 ubuntu server 虚拟机,实现基于 linux bridge 的软交换功能
  6. 修改 pve 的管理网络为使用 40G 高速网络
  7. 拆除现有网络,改用 openwrt 拨号并接入内网设备
  8. 修改 openwrt 的临时网段为正式网段

解释: 为什么不在 openwrt 中直接管理两块 40G 网卡?

  • 最主要的原因是 openwrt 不支持 RDMA, 因此会有非常巨大的性能损失(超出50%)而且cpu消耗非常高
  • openwrt 下 40G 网卡 (具体型号为 hp544+)的启用和停用,会影响 openwrt 下的网络命名 (eth0/eth1/eth2等的存在和顺序),而 openwrt 的 lan / wan 是绑定在 eth0 这样的名称上,而不是具体的 mac 地址上。因此如果下有的 40G 网络设备有启动或者停止,而 openwrt 又进行了重启,则会因为eth网卡顺序和名称的变化造成 openwrt 不可用。

准备工作

准备虚拟机

分别建立两个虚拟机:

  1. 用于软路由的 openwrt

    安装的方法参考 https://skyao.io/learning-openwrt/docs/installation/pve/

    注意: 先不要开启开机自动启动

  2. 用于软交换的 ubuntu server 20.04

网卡基本情况

lspci | grep controller

可以看到 pci 设备情况:

01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
04:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)
07:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)

四块网卡网卡的设备 id 依次是 01/04/06/07。

对应他们的网络设备名称,执行

ip addr

可以看到:

2: enp6s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vmbr0 state UP group default qlen 1000
    link/ether 38:ca:73:fe:01:60 brd ff:ff:ff:ff:ff:ff
3: enp7s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 58:11:22:08:76:ed brd ff:ff:ff:ff:ff:ff
4: enp1s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 50:65:f3:89:24:21 brd ff:ff:ff:ff:ff:ff
5: enp1s0d1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 50:65:f3:89:24:22 brd ff:ff:ff:ff:ff:ff
6: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 50:65:f3:89:b4:61 brd ff:ff:ff:ff:ff:ff
7: enp4s0d1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 50:65:f3:89:b4:62 brd ff:ff:ff:ff:ff:ff
......
16: vmbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 38:ca:73:fe:01:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.8/24 scope global vmbr0
  • enp6s0: 2.5G 网卡,这块卡按照规划是 openwrt 的 wan 口
  • enp7s0: 2.5G 网卡,这块卡按照规划是 openwrt 的 lan 口,同时也是 ubuntu server 的 wan 口
  • enp1s0 / enp1s0d1: 第一块(离cpu近) 40G 网卡的两个 port ,这个网卡准备直通给到软交换的 ubuntu server 虚拟机
  • enp4s0 / enp4s0d1: 第二块 40G 网卡的两个 port ,需要做 SR-IOV,同时用于管理网络/软交换的 ubuntu server 虚拟机/其他虚拟机
  • vmbr0: 管理网络使用的网桥,绑定在 enp7s0 上
  • 新加 vmbr1:未来管理网络将要使用的网桥,绑定在 enp4s0 上,因此暂时没有设置 ip 地址和网关

pve-network

准备本地机器

需要准备一台本地机器,作为客户端接入到软路由和软交换的两个网段,因此要求这个机器有两块网卡,分别接入这两个网段。

实际操作时也可以用两台机器分别接入 2.5G 和 40G 网络。

准备网卡的直通和开启SR-IOV

按照前面的做法, 开启 PVE 的直通支持,并将两块 40G 网卡中的第二块(离cpu远的)设置为开启 SR-IOV。注意:第一块 40G 网卡不要开启 SR-IOV。

lspci | grep controller

查看设置完成之后的网卡设备情况(忽略其他设备):

......
01:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
04:00.0 Ethernet controller: Mellanox Technologies MT27520 Family [ConnectX-3 Pro]
04:00.1 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.2 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.3 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.4 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.5 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.6 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:00.7 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
04:01.0 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)
07:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)

在 pve 中看到的网络情况:

pve-network2

目前 vmbr0 绑定在 enp7s0 这块 2.5G 网卡上。

网段规划和网卡分工

规划有两个网段:

  • 192.168.0.0/24: 这是软路由的目标网段,openwrt 软路由地址为 192.168.0.1,作为 192.168.0.0/24 网段的网关

    • 注意,在实施过程时,因为现有网络使用了 192.168.0.0/24 网段,因此 openwrt 会先临时使用 192.168.5.0/24 网段,待一切完成后,再改为 192.168.0.0/24 网段
  • 192.168.99.0/24: 这是软交换的网段,ubuntu server 软路由地址为 192.168.99.1,作为 192.168.99.0/24 网段的网关

刚开始时,由其他路由器拨号,pve 主机安装和配置过程中都需要使用到网络,因此安装 pve 时使用 2.5g 网卡 enp7s0 作为 pve 管理网络(绑定到 vmbr0),此时的 ip 地址是 192.168.0.8,如上图所示。

vmbr0 以及它绑定的网卡(现在是 2.5G 的 enp7s0)需要扮演三个角色:

  1. 作为 lan 接入到软路由 openwrt 中
  2. 作为 wan 接入到软交换 ubuntu server 中
  3. 作为管理网络接口提供远程管理功能: 这个功能在最后会被基于 enp4s0 的 vmbr1 取代

说明: 由于在安装 pve 时 40G高速网段不可用(软交换所在的 pve 还没有安装),因此只能将 vmbr0 绑定 2.5G 网卡。但后续为了速度起见还是会使用 40G 作为管理网络。

给两个虚拟机分别分配网卡。

注意: 要先将虚拟机关机再修改硬件配置,否则无法生效,包括重启之后也无法生效,需要停机/删除/再次添加。

这是 openwrt 的虚拟机,除了分配 vmbr0 外,还需要将另外一块 2.5G 网卡直通进入,充当 openwrt 的 wan 和 lan:

openwrt-nic-list

切记: 直通网卡时千万不要弄错,别把 pve 的管理网络所在的网卡(也就是vmbr0对应的网卡)给直通进去了,那样会导致管理网络无法使用。只能通过 pve 控制台来进行操作。

ubuntu server 的虚拟机,除了需要将使用 vmbr0 作为 wan 之外,还需要将两块 40G 网卡的四个端口都直通进去,其中第二块网卡开启了 SR-IOV,因此直通的是编号为1和5的两个 VF:

ubuntu-server-nic-list

至此虚拟机和网卡就都准备好了,开始正式配置软路由和软交换

配置软路由 openwrt

将两块网卡给到 openwrt 虚拟机:

  1. 设备id 为 06 的 2.5G 网卡: 直通
  2. 设备id 为 07 的 2.5G 网卡: 以 vmbr0 的方式

之后两块2.5G网络将分别作为 wan 和 lan。

配置 openwrt 虚拟机

启动 openwrt 虚拟机,此时可以通过管理页面来操作,或者直接在机器的控制台操作。执行:

ip addr

可以看到 eth0 / eth1 两块网卡:

openwrt-ip-addr

执行

lspci

同样能看到两块网卡:

openwrt-lspci

其中一块是直通的,因此能看到型号 RTL8125。另一块是以 vmbr0 的形式,采用的是 Virtio 模式,因此看到的是 “virtio network device”。

但现在看不出来 eth0 / eth1 和两块网卡之间的对应关系。但有个简单的办法,就是拔掉网线,只保留 vmbr0 对应的网卡有网线,然后就可以通过网卡的 UP 状态来识别了。

修改 openwrt 的 /etc/config/network 文件,将 lan 设置为 eth0, ipaddr 设置为 192.168.0.1。拔掉 wan 口的网线,然后重启 openwrt。

此时,会有两个 192.168.0.1/24 网段: 1. 原有的网络 2. 新的 openwrt 的网络

下面我们要将本地机器接入到新的 openwrt 的网络进行后续操作。

本地机器接入软路由网络

此时在本地机器上,连接作为 openwrt lan 口的 2.5g网卡, 接入 openwrt 的 192.168.0.0/24 网段:

local-nic-2.5g

此时本地机器就成功的接入了 openwrt 的 192.168.0.0/24 ,可以通过访问 http://192.168.0.1/ 来管理 openwrt ,也可以通过访问 https://192.168.0.8:8006/ 来操作 pve。

启用 openwrt 软路由

在本地机器上打开 http://192.168.0.1/ ,登录进入,执行 openwrt 的各种设置(或者直接倒入之前备份的配置)。

我这里因为之前有备份的配置,因此直接导入。openwrt 会自动重启,之后重新登录。

此时 openwrt 就准备好了,除了 wan 口还没有接入光猫来进行拨号,以及还没有接入内网 2.5g 交换机。

去掉之前使用的路由器,连接 openwrt 的 万口和 光猫,改由 openwrt 拨号。并将 内网 2.5g 交换机接入 opemwrt 的 lan 口。

一切搞定之后,关闭 openwrt, 然后在设置中开启自动启动。再重启 pve 机器,验证一下。

至此 openwrt 软路由完成。

搭建软交换

在 ubuntu server 虚拟机上设置网卡,将

  • 设备id 为 04 的 40G 网卡的第一个端口的第一个 VF:

    04:00.1 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]

  • 设备id 为 04 的 40G 网卡的第二个端口的第一个 VF:

    04:00.5 Ethernet controller: Mellanox Technologies MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]

  • 设备id 为 01 的 40G 网卡: 整个网卡直通进入,注意不是 VF,这块网卡特意没有开启 SR-IOV

switch-nic

开启 ubuntu server 虚拟机,登录进入后执行

ip addr

可以看到此时 enp1s0 已经自动获取了 192.168.0.0/24 网段的地址:

switch-ip-addr

这是因为 enp1s0 是 VF,而另外一个 VF 在前面被我们直通给了 openwrt 主机。两个网段之间的联系(包括和管理网络的联系)就是通过这样的方式建立起来的。

之后按照软交换的设置方式,参考 https://skyao.io/learning-ubuntu-server/docs/router/router.html

切换管理网络为高速网络

在两个虚拟机准备好之后,第一件事情是修改为采用 40G 高速网络进行 pve 管理,以便后续将两块 2.5g 网卡都直通给到 openwrt 的虚拟机。

现在我们要做的是修改 vmbr0 的设置,让它绑定在 enp4s0 这块 40G 网卡的 port1 上。

先将一台电脑的 40G 网卡和 pve 所在机器的这块40G网卡的 port 1 (两个网口中更靠近主板的那个)连接,后续就只能依靠这条网络来远程管理 pve。

更换管理网络的事情最好还是在 pve 机器控制台上进行,因为中途管理网络会中断。

修改 /etc/network/interfaces 中 vmbr0 对应的网卡,从原有的 enp6s0 修改为 enp4s0,然后设置:

  • ip地址为 192.168.99.8
  • 子网掩码为 255.255.255.0
  • 网关为 192.168.99.1: 这个网关现在还不存在,未来将在软交换 ubuntu server 中创建,但不影响现在的使用

然后重启 pve。

本地机器接入软交换网络

PVE 重启完成后,设置本地机器的 40G 网卡:

  • ip地址为 192.168.99.90
  • 子网掩码为 255.255.255.0
  • 网关为 192.168.99.8: 目前网关不存在,就只能指定为网线直连的对端的 ip 地址

本地40G网卡连接情况如图所示:

local-nic

之后通过 https://192.168.99.8:8006/ 就可以访问到 pve 机器的新的管理网络了,后续操作都将在远程进行。

4.3 - 高速共享存储

开启直通来建立高速的共享存储

背景

需求:

  • 希望在局域网内为其他机器提供高速网络共享服务

设备:

  • 一块 40G/56G 网卡,型号为 HP544+,双口(但当前实战中只使用到一个口)
  • 一块爱国者p7000z 4T pcie 4.0 硬盘
  • 一块华硕z690-p d4 主板

目标:

  • 虚拟机拥有 56G 高速网络,同时可以高速读写那块 4T 的 pcie4 ssd 硬盘

规划方案1

  • HP544+ 网卡直通给到虚拟机
  • p7000z 硬盘直通给到虚拟机

规划方案2:

  • HP544+ 网卡直通给到虚拟机
  • p7000z 硬盘由 pve 管理,然后以 pve hard disk 的方式传递给虚拟机

遇到问题修改规划

规划1 在实践时遇到问题,HP544+ 网卡和 p7000z 硬盘都可以单独直通给到虚拟机,但是如果两个设备同时一起直通给到虚拟机,则会报错:

kvm: -device vfio-pci,host=0000:01:00.0,id=hostpci1,bus=ich9-pcie-port-2,addr=0x0: vfio 0000:01:00.0: Failed to set up TRIGGER eventfd signaling for interrupt INTX-0: VFIO_DEVICE_SET_IRQS failure: Device or resource busy
TASK ERROR: start failed: QEMU exited with code 1

google 一番没有找到解决方案,倒是找到了一个问题和我类似的帖子:

https://forum.proxmox.com/threads/passthrough-two-pci-devices.110397/

作者说问题发生在使用两块 Mellanox ConnectX-3 网卡时,当他换成 Mellanox ConnectX-4 网卡时问题就消失了。

考虑到目前我还没有换 Mellanox ConnectX-4 的计划,只能放弃规划方案1, 后面的操作是基于规划方案2。

准备工作

准备 PVE 和直通支持

安装 pve 8.0, 开启直通支持。

准备虚拟机

安装 ubuntu server 20.04, 按照之前虚拟机的要求为直通做好准备。

实战步骤

速度对比