我遇到了一个奇怪的问题。我一直在努力让 GPU 直通在 Windows 11 虚拟机上正常工作,我终于找到了一些可行的方法,但它并不像我希望的那么理想。本质上,如果我在启动时将 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 时,一切看起来都很好,但 torch 无法再检测到 GPU。有任何想法吗?
我的解决方法目前可以正常工作,但如果我想启动虚拟机,则需要重新启动。理想情况下,当我想在主机上使用它与在 Windows 11 虚拟机中使用它之间进行切换时,我希望能够按需绑定/取消绑定我的 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
我感觉很清楚,尽管某些东西正在使用 vfio-pci 内核驱动程序并lsof /dev/nvidia0
返回一个空字符串,但它仍然以某种方式使用 nvidia。有任何想法吗?我在这里有点疯狂!
经过更多调查后,我发现这是同样的问题:https://www.reddit.com/r/VFIO/s/ASQ3Bx3RGq
相关问题跟踪器:https://gitlab.freedesktop.org/drm/amd/-/issues/2794
基本上,这可以归结为这样一个事实:我尝试在主机上的 AMD CPU 上使用 iGPU,并使用 NVIDIA GPU 进行直通。显然,这是由于 AMD 和 NVIDIA 上的缓存技术不同,并且内核目前无法妥善处理该问题。此存储库提供了有关如何修补内核的提示:https://github.com/Kinsteen/win10-gpu-passthrough
因为在使用 VM 时我不太关心使用主机显示器,所以我只是继续将 amdgpu 列入黑名单,并在启动 Windows 11 VM 之前终止我的显示管理器。效果很好。
在此之前,我尝试升级到 Ubuntu 24,因为我听说这个问题已在 Kernel 6.6 中修复,而 Ubuntu 24 使用 Kernel 6.8,但可惜我最终遇到了同样的问题。因此,单 GPU 直通似乎是目前的最佳选择。