Intel VT-d快速起步

KVM中性能最好的磁盘IO是 pass-through ,即 IOMMU 技术。这项技术在Intel中称为 VT-d ,本文就是在 HPE ProLiant DL360 Gen9服务器 服务器上实现 私有云架构 ,在最底层的第一层虚拟化中,即采用虚拟机直接访问存储,以实现最好的I/O性能。

具体实现:

  • HDD磁盘2块,分别 assignz-gluster-1z-gluster-2 ,部署 Gluster Atlas

  • 使用NVMe 存储卡(4个slot),安装4个m.2的NVMe存储,其中3个NVMe存储通过 pass-through 直接 assignz-ceph-1z-ceph-2z-ceph-3 虚拟机,部署 Ceph Atlas

准备工作

  • 服务器BIOS激活 VT-d

  • Ubuntu Linux 内核默认已经编译支持了 IOMMU ,通过以下方式检查:

    dmesg | grep -e DMAR -e IOMMU
    

输出显示:

intel_vt-d_startup/dmesg_no_iommu.txt
 1[    0.009945 ] ACPI: DMAR 0x000000007B7E7000 000262 (v01 HP     ProLiant 00000001 HP   00000001)
 2[    0.009981 ] ACPI: Reserving DMAR table memory at [mem 0x7b7e7000-0x7b7e7261]
 3[    0.505971 ] DMAR: Host address width 46
 4[    0.505973 ] DMAR: DRHD base: 0x000000fbffc000 flags: 0x0
 5[    0.505979 ] DMAR: dmar0: reg_base_addr fbffc000 ver 1:0 cap d2078c106f0466 ecap f020df
 6[    0.505982 ] DMAR: DRHD base: 0x000000c7ffc000 flags: 0x1
 7[    0.505986 ] DMAR: dmar1: reg_base_addr c7ffc000 ver 1:0 cap d2078c106f0466 ecap f020df
 8[    0.505989 ] DMAR: RMRR base: 0x00000079173000 end: 0x00000079175fff
 9[    0.505991 ] DMAR: RMRR base: 0x000000791ec000 end: 0x000000791effff
10[    0.505993 ] DMAR: RMRR base: 0x000000791dc000 end: 0x000000791ebfff
11[    0.505995 ] DMAR: RMRR base: 0x000000791c9000 end: 0x000000791d9fff
12[    0.505997 ] DMAR: RMRR base: 0x000000791da000 end: 0x000000791dbfff
13[    0.506000 ] DMAR-IR: IOAPIC id 10 under DRHD base  0xfbffc000 IOMMU 0
14[    0.506002 ] DMAR-IR: IOAPIC id 8 under DRHD base  0xc7ffc000 IOMMU 1
15[    0.506004 ] DMAR-IR: IOAPIC id 9 under DRHD base  0xc7ffc000 IOMMU 1
16[    0.506006 ] DMAR-IR: HPET id 0 under DRHD base 0xc7ffc000
17[    0.506008 ] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
18[    0.506538 ] DMAR-IR: Enabled IRQ remapping in x2apic mode

需要注意,此时还没有看到内核激活IOMMU,必须要看到 DMAR: IOMMU enabled 才是真正激活

备注

如果使用AMD处理器,则内核参数可以使用以下配置:

iommu=pt iommu=1    # AMD only

iommu=pt 可以避免Linux使用不能pass-through的设备,详见 IOMMU内核启动grub配置

然后更新grub:

sudo update-grub

备注

如果是CentOS/RHEL 则使用 grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg 命令

并重启系统,然后检查 cat /proc/cmdline 可以看到:

... intel_iommu=on
  • 重启完成后检查 dmesg | grep -e DMAR -e IOMMU 可以看到输出中多了几行内容:

intel_vt-d_startup/dmesg_iommu.txt
 1[    0.010070] ACPI: DMAR 0x000000007B7E7000 000262 (v01 HP     ProLiant 00000001 HP   00000001)
 2[    0.010106] ACPI: Reserving DMAR table memory at [mem 0x7b7e7000-0x7b7e7261]
 3[    0.251980] DMAR: IOMMU enabled
 4[    0.507263] DMAR: Host address width 46
 5[    0.507266] DMAR: DRHD base: 0x000000fbffc000 flags: 0x0
 6[    0.507273] DMAR: dmar0: reg_base_addr fbffc000 ver 1:0 cap d2078c106f0466 ecap f020df
 7[    0.507276] DMAR: DRHD base: 0x000000c7ffc000 flags: 0x1
 8[    0.507280] DMAR: dmar1: reg_base_addr c7ffc000 ver 1:0 cap d2078c106f0466 ecap f020df
 9[    0.507283] DMAR: RMRR base: 0x00000079173000 end: 0x00000079175fff
10[    0.507285] DMAR: RMRR base: 0x000000791ec000 end: 0x000000791effff
11[    0.507287] DMAR: RMRR base: 0x000000791dc000 end: 0x000000791ebfff
12[    0.507289] DMAR: RMRR base: 0x000000791c9000 end: 0x000000791d9fff
13[    0.507291] DMAR: RMRR base: 0x000000791da000 end: 0x000000791dbfff
14[    0.507294] DMAR-IR: IOAPIC id 10 under DRHD base  0xfbffc000 IOMMU 0
15[    0.507296] DMAR-IR: IOAPIC id 8 under DRHD base  0xc7ffc000 IOMMU 1
16[    0.507298] DMAR-IR: IOAPIC id 9 under DRHD base  0xc7ffc000 IOMMU 1
17[    0.507300] DMAR-IR: HPET id 0 under DRHD base 0xc7ffc000
18[    0.507302] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
19[    0.507832] DMAR-IR: Enabled IRQ remapping in x2apic mode
20[    1.085368] DMAR: No ATSR found
21[    1.085770] DMAR: dmar0: Using Queued invalidation
22[    1.085782] DMAR: dmar1: Using Queued invalidation
23[    1.138764] DMAR: Intel(R) Virtualization Technology for Directed I/O

确认IOMMU groups

以下脚本 check_iommu.sh 脚本可以查看系统中不同的PCI设备被映射到IOMMU组,如果没有返回任何信息,则表明系统没有激活IOMMU支持或者硬件不支持IOMMU

检查PCI设备映射到IOMMU组
#!/bin/bash
shopt -s nullglob
for g in `find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V`; do
    echo "IOMMU Group ${g##*/}:"
    for d in $g/devices/*; do
        echo -e "\t$(lspci -nns ${d##*/})"
    done;
done;

Host主机unbind设备

要将PCI设备直通给虚拟机,需要首先在Host物理主机上 unbind 这个PCI设备,也就是在物理主机上这个设备将 消失 ,然后 asign 设备给虚拟机,这样这个设备就是虚拟机 独占 使用

备注

由于我实践方案修改,所以 Intel VT-d 实践改为在 Open Virtual Machine Firmware(OMVF) 完成。后续等再次实践时补充完善本文

参考