第 15 章 在虚拟机中管理 GPU 设备

要在 RHEL 9 主机上增强虚拟机(VM)的图形性能,您可以将主机 GPU 分配给虚拟机。

  • 您可以从主机中分离 GPU,并将 GPU 直接控制传递给虚拟机。
  • 您可以从物理 GPU 创建多个中介设备,并将这些设备作为虚拟 GPU(vGPU)分配给多个客户机。目前仅支持所选的 NVIDIA GPU,且只能为单个客户机分配一个中介设备。

15.1. 为虚拟机分配 GPU

要访问并控制附加到主机系统的 GPU,您必须将主机系统配置为将 GPU 的直接控制传给虚拟机(VM)。

注意

如果您要查找有关分配虚拟 GPU 的信息,请参阅管理 NVIDIA vGPU 设备

先决条件

  • 您必须在主机机器内核中启用 IOMMU 支持。

    • 在 Intel 主机上,您必须启用 VT-d:

      1. 使用 intel_iommu=oniommu=pt 参数重新生成 GRUB 配置:

        # grubby --args="intel_iommu=on iommu_pt" --update-kernel DEFAULT
      2. 重启主机。
    • 在 AMD 主机上,您必须启用 AMD-Vi。

      请注意,在 AMD 主机上,默认启用 IOMMU,您可以添加 iommu=pt 将其切换到直通模式:

      1. 使用 iommu=pt 参数重新生成 GRUB 配置:

        # grubby --args="iommu=pt" --update-kernel DEFAULT
        注意

        pt 选项只为直通模式中使用的设备启用 IOMMU,并提供更好的主机性能。但是,并非所有硬件都支持这个选项。无论是否启用了这个选项,您仍然可以分配设备。

      2. 重启主机。

流程

  1. 防止驱动程序绑定到 GPU。

    1. 识别 GPU 连接到的 PCI 总线地址。

      # lspci -Dnn | grep VGA
      0000:02:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK106GL [Quadro K4000] [10de:11fa] (rev a1)
    2. 防止主机的图形驱动程序使用 GPU。要做到这一点,使用带有 pci-stub 驱动程序的 GPU PCI ID。

      例如,以下命令可防止驱动程序绑定到附加在 10de:11fa 总线的 GPU:

      # grubby --args="pci-stub.ids=10de:11fa" --update-kernel DEFAULT
    3. 重启主机。
  2. 可选: 如果因为支持的限制而无法将某些 GPU 功能(如音频)直通给虚拟机,您可以修改 IOMMU 组中端点的驱动程序绑定,使其只能直通必要的 GPU 功能。

    1. 将 GPU 设置转换为 XML,并记下要防止附加到主机驱动程序的端点的 PCI 地址。

      为此,通过向地址添加 pci_ 前缀,将 GPU 的 PCI 总线地址转换为 libvirt 兼容的格式,并将分隔符转换为下划线。

      例如,以下命令显示附加在 0000:02:00.0 总线地址的 GPU 的 XML 配置。

      # virsh nodedev-dumpxml pci_0000_02_00_0
      <device>
       <name>pci_0000_02_00_0</name>
       <path>/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.0</path>
       <parent>pci_0000_00_03_0</parent>
       <driver>
        <name>pci-stub</name>
       </driver>
       <capability type='pci'>
        <domain>0</domain>
        <bus>2</bus>
        <slot>0</slot>
        <function>0</function>
        <product id='0x11fa'>GK106GL [Quadro K4000]</product>
        <vendor id='0x10de'>NVIDIA Corporation</vendor>
        <iommuGroup number='13'>
         <address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
         <address domain='0x0000' bus='0x02' slot='0x00' function='0x1'/>
        </iommuGroup>
        <pci-express>
         <link validity='cap' port='0' speed='8' width='16'/>
         <link validity='sta' speed='2.5' width='16'/>
        </pci-express>
       </capability>
      </device>
    2. 防止端点附加到主机驱动程序。

      在本例中,要将 GPU 分配给虚拟机,防止与音频功能对应的端点 <address domain='0x0000' bus='0x02' slot='0x00' function='0x1'/> 附加到主机音频驱动程序,请将端点附加到 VFIO-PCI。

      # driverctl set-override 0000:02:00.1 vfio-pci
  3. 将 GPU 附加到虚拟机

    1. 使用 PCI 总线地址为 GPU 创建 XML 配置文件。

      例如,您可以使用 GPU 总线地址中的参数创建以下 XML 文件,GPU-Assign.xml。

      <hostdev mode='subsystem' type='pci' managed='yes'>
       <driver name='vfio'/>
       <source>
        <address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
       </source>
      </hostdev>
    2. 将文件保存到主机系统上。
    3. 将文件与虚拟机的 XML 配置合并。

      例如,以下命令将 GPU XML 文件 GPU-Assign.xml 与 System1 虚拟机的 XML 配置文件合并:

      # virsh attach-device System1 --file /home/GPU-Assign.xml --persistent
      Device attached successfully.
      注意

      GPU 是作为辅助图形设备附加到虚拟机的。不支持将 GPU 分配为主图形设备,红帽不建议删除虚拟机 XML 配置中的主模拟图形设备。

验证

已知问题

  • 可附加到虚拟机的 GPU 数量受分配的 PCI 设备的最大数量限制,在 RHEL 9 中,当前为 64。但是,将多个 GPU 附加到虚拟机可能会导致客户端上内存映射 I/O (MMIO) 出现问题,这可能会导致 GPU 无法对虚拟机使用。

    要临时解决这个问题,请设置较大的 64 位 MMIO 空间并配置 vCPU 物理地址位,以使扩展 64 位 MMIO 空间可以寻址。

  • 将 NVIDIA GPU 设备附加到使用 RHEL 9 客户机操作系统的虚拟机当前会禁用该虚拟机上的 Wayland 会话,而改为加载 Xorg 会话。这是因为 NVIDIA 驱动程序和 Wayland 之间的不兼容。