无法根据需要正确将 GPU 从 nvidia 绑定/解除绑定到 vfio-pci,无需重启(Ubuntu 22 QEMU KVM OVMF)

无法根据需要正确将 GPU 从 nvidia 绑定/解除绑定到 vfio-pci,无需重启(Ubuntu 22 QEMU KVM OVMF)

我遇到了一个奇怪的问题。我一直在努力让 GPU 直通正确地运行到 Windows 11 VM,我终于找到了一种可行的方法,但它并不像我希望的那样理想。本质上,如果我在启动时将 VFIO 绑定添加到/etc/modprobe.d/vfio.conf我的 PCI ID options vfio-pci ids=10de:2684,10de:22ba ,我就可以很好地使用它进行 GPU 直通。但如果我尝试将 GPU 重新连接到 nvidia 驱动程序,我似乎无法将它与 pytorch 一起使用(尽管nvidia-smi工作正常)。

如果我删除该 vfio.conf 文件并重新启动,GPU 将绑定到 nvidia,并且 torch 可以正常工作,但是当我尝试从 nvidia 解除绑定并绑定到 vfio-pci 时,当我启动 VM 时,我会在 Nvidia 驱动程序上收到错误代码 43,并且在 libvirt 日志中出现以下错误:

2024-04-09T15:38:49.796258Z qemu-system-x86_64: -device vfio-pci,host=0000:01:00.0,id=hostdev0,bus=pci.5,addr=0x0: Failed to mmap 0000:01:00.0 BAR 1. Performance may be slow
2024-04-09T15:39:07.971124Z qemu-system-x86_64: vfio_region_write(0000:01:00.0:region1+0x8c, 0x1,4) failed: Cannot allocate memory

这真的很奇怪,因为从我的所有检查来看,GPU 似乎被正确隔离了,但似乎我无法在没有明确绑定到 vfio via 的情况下将其传递到 GPU /etc/modprobe.d/vfio.conf,而当我这样做时,我似乎无法正确地将其绑定回 nvidia。再次,当我将其重新绑定到 nvidia 时,一切看起来都很好,但 torch 无法再检测到 GPU。有什么想法吗?

我的解决方法目前可以​​正常工作,但如果我想启动我的虚拟机,则需要重新启动。当我想在主机和 Windows 11 VM 之间切换使用 nvidia GPU 时,我理想情况下希望能够按需绑定/取消绑定它。绑定到 VFIO 脚本的示例:

#!/bin/bash
set -x

# Stop display manager
systemctl stop display-manager

# Unbind VTconsoles: might not be needed
echo 0 > /sys/class/vtconsole/vtcon0/bind
echo 0 > /sys/class/vtconsole/vtcon1/bind

# Unload NVIDIA kernel modules
modprobe -r nvidia_drm 
modprobe -r nvidia_modeset
modprobe -r nvidia_uvm 
modprobe -r nvidia

# Detach GPU devices from host
# Use your GPU and HDMI Audio PCI host device
sudo virsh nodedev-detach pci_0000_01_00_0
sudo virsh nodedev-detach pci_0000_01_00_1

# Load vfio module
modprobe vfio-pci

如果我跑

lspci -nnk -d 10de:2684
lspci -nnk -d 10de:22ba

它看起来正确绑定到 vfio-pci:

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2684] (rev a1)
        Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
        Kernel driver in use: vfio-pci
        Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:22ba] (rev a1)
        Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
        Kernel driver in use: vfio-pci
        Kernel modules: snd_hda_intel

如果我重新启动并应用 vfio.conf 并检查内容,它看起来是一样的,但奇怪的是,在启动我的 Windows 11 VM 时确实有效:

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2684] (rev a1)
        Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
        Kernel driver in use: vfio-pci
        Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:22ba] (rev a1)
        Subsystem: Gigabyte Technology Co., Ltd Device [1458:40e5]
        Kernel driver in use: vfio-pci
        Kernel modules: snd_hda_intel

但是如果我随后解除与 vfio 的绑定并绑定到 nvidia:

#!/bin/bash
set -x

# Attach GPU devices to host
# Use your GPU and HDMI Audio PCI host device
sudo virsh nodedev-reattach pci_0000_01_00_0
sudo virsh nodedev-reattach pci_0000_01_00_1

# Unload vfio module
modprobe -r vfio-pci

#stop race condition
sleep 2

# Load NVIDIA kernel modules
modprobe nvidia
modprobe nvidia_modeset
modprobe nvidia_uvm
modprobe nvidia_drm

# Bind VTconsoles: might not be needed
echo 1 > /sys/class/vtconsole/vtcon0/bind
echo 1 > /sys/class/vtconsole/vtcon1/bind

nvidia-smi工作正常:

+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.161.07             Driver Version: 535.161.07   CUDA Version: 12.2     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA GeForce RTX 4090        Off | 00000000:01:00.0 Off |                  Off |
|  0%   49C    P0              67W / 450W |      0MiB / 24564MiB |      0%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+
                                                                                         
+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|  No running processes found                                                           |
+---------------------------------------------------------------------------------------+

但是当我在 Docker 中运行使用 pytorch 的某些东西时:

RuntimeError: Torch is not able to use GPU

更糟糕的是,当我尝试重新绑定到 vfio 时,它就像我没有启用一样工作vfio.conf,并且在启动 Windows 11 VM 时出现同样的错误:

2024-04-09T16:04:45.089687Z qemu-system-x86_64: -device vfio-pci,host=0000:01:00.0,id=hostdev0,bus=pci.5,addr=0x0: Failed to mmap 0000:01:00.0 BAR 1. Performance may be slow
2024-04-09T16:04:55.682373Z qemu-system-x86_64: vfio_region_write(0000:01:00.0:region1+0x8c, 0x1,4) failed: Cannot allocate memory

我觉得很明显,某些东西仍在以某种方式使用 nvidia,即使它正在使用 vfio-pci 内核驱动程序并lsof /dev/nvidia0返回一个空白字符串。有什么想法吗?我有点疯了!

答案1

经过进一步调查后,我发现这是同样的问题:https://www.reddit.com/r/VFIO/s/ASQ3Bx3RGq

相关问题追踪:https://gitlab.freedesktop.org/drm/amd/-/issues/2794

基本上,这归结于我试图在主机上使用 AMD CPU 上的 iGPU 和 NVIDIA GPU 进行直通。显然,这是因为 AMD 和 NVIDIA 上的缓存技术不同,而内核目前无法很好地处理这个问题。此 repo 提供了有关如何修补内核的提示:https://github.com/Kinsteen/win10-gpu-passthrough

由于在使用虚拟机时我不太在意主机显示器的使用,因此我直接将 amdgpu 列入黑名单,并在启动 Windows 11 虚拟机之前关闭显示管理器。效果很好。

在此之前,我尝试升级到 Ubuntu 24,因为我听说这个问题在内核 6.6 中已修复,而 Ubuntu 24 使用内核 6.8,但不幸的是,我最终遇到了同样的问题。因此,单 GPU 直通似乎是目前最好的选择。

相关内容