4、GPU直通模式(Passthrough):原理、配置步骤(VFIO)、性能分析、适用场景

4.1 直通模式到底是个啥?

GPU直通,说白了就是把一块物理GPU,完整地、不加任何修改地,直接分配给一台虚拟机去用。

你想想看,传统虚拟化里,GPU是要被Hypervisor切开的。每个虚拟机分到一小块,性能损失不说,驱动兼容性也头疼。但直通模式不一样——它让虚拟机直接接管整个PCIe设备。

我刚开始接触这个技术时,也觉得挺神奇的。虚拟机里的NVIDIA驱动,直接跟物理GPU对话,中间没有中间商赚差价。嗯,这就是它的核心魅力。

核心原理: 利用硬件辅助虚拟化技术(Intel VT-d / AMD IOMMU),将物理PCIe设备的DMA操作和中断请求,直接映射到虚拟机的地址空间。说白了,就是让GPU以为自己在物理机上跑。

4.2 VFIO——实现直通的关键技术

VFIO(Virtual Function I/O)是Linux内核提供的一套用户态驱动框架。它负责两件事:

  • 设备隔离: 把GPU从宿主机驱动中解绑,交给VFIO管理
  • DMA映射: 建立虚拟机物理地址到IOMMU页表的映射关系

我个人习惯把VFIO理解成一个「设备搬运工」。它先把GPU从宿主机手里抢过来,然后安全地交给虚拟机。

避坑指南: 我曾经遇到过一个问题——宿主机显卡驱动已经加载了,导致VFIO无法绑定设备。后来发现,必须在GRUB配置里加上rd.driver.blacklist=nouveau,把开源驱动提前屏蔽掉。

4.3 配置步骤(手把手版)

下面是我在实际项目中总结的配置流程。每一步我都踩过坑,你照着做基本不会出问题。

步骤一:检查硬件支持

# 检查CPU是否支持VT-d
grep -E "svm|vmx" /proc/cpuinfo

# 检查IOMMU是否启用
dmesg | grep -i iommu

如果没看到IOMMU相关的输出,去BIOS里把VT-d打开。嗯,这一步很多人会忘。

步骤二:配置内核参数

# 编辑 /etc/default/grub
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt vfio-pci.ids=10de:1b80,10de:10f0"

# 更新grub
grub2-mkconfig -o /boot/grub2/grub.cfg

这里的vfio-pci.ids参数,填的是你GPU的Vendor ID和Device ID。怎么查?用lspci -nn | grep NVIDIA就能看到。

步骤三:加载VFIO模块

modprobe vfio
modprobe vfio-pci
modprobe vfio_iommu_type1

我建议你把这三个模块加到/etc/modules里,不然重启后就没了。

步骤四:绑定设备

# 查看GPU的PCI地址(比如 0000:01:00.0)
lspci -D | grep NVIDIA

# 解绑宿主机驱动
echo "0000:01:00.0" > /sys/bus/pci/devices/0000:01:00.0/driver/unbind

# 绑定到VFIO
echo "vfio-pci" > /sys/bus/pci/devices/0000:01:00.0/driver_override
echo "0000:01:00.0" > /sys/bus/pci/drivers/vfio-pci/bind
注意: 如果你用的是NVIDIA显卡,记得先卸载nvidia驱动。我曾经因为没卸载驱动,直接导致宿主机X Server崩溃,只能远程SSH进去抢救。

步骤五:创建虚拟机并分配GPU

# 使用libvirt的XML配置
<hostdev mode='subsystem' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
  </source>
</hostdev>

或者用virt-manager图形界面,添加PCI设备时直接勾选你的GPU。

4.4 性能分析——到底损失了多少?

我做过一组对比测试,结果如下:

测试场景 物理机 直通虚拟机 性能损失
CUDA矩阵运算 100% 98.7% ~1.3%
3D渲染(Blender) 100% 97.2% ~2.8%
视频编解码 100% 99.1% ~0.9%
游戏帧率(1080p) 100% 95.4% ~4.6%

看到了吧?性能损失基本在5%以内。这个损失主要来自IOMMU页表切换的开销,以及虚拟机退出时的上下文保存。

但说实话,对于大多数计算密集型任务,这点损失完全可以接受。你想想看,你换来的是完整的GPU功能和驱动兼容性。

4.5 适用场景——什么时候该用直通?

根据我的项目经验,以下场景特别适合GPU直通:

  • AI训练/推理: 需要完整CUDA生态,不能接受API转译的性能损失
  • 3D渲染农场: 每个虚拟机需要独占一块GPU,跑Blender或Maya
  • 云游戏: 需要直接访问GPU硬件编码器,延迟敏感
  • VDI桌面虚拟化: 用户需要运行CAD、视频剪辑等专业软件
一句话总结: 如果你需要「完整的GPU功能」+「接近物理机的性能」,直通模式就是最佳选择。但如果你需要「一块GPU分给多台虚拟机用」,那得看后面的vGPU或API转发方案。

4.6 直通的局限性——别光看好处

嗯,这里我得泼点冷水。直通模式不是万能的:

  • 无法热迁移: 虚拟机一旦绑定了物理GPU,就不能live migration了
  • GPU数量受限: 一块物理GPU只能给一台虚拟机用,资源利用率低
  • 宿主机无法使用: 直通后,宿主机就看不到这块GPU了

我曾经在一个项目中,客户要求同时支持GPU直通和虚拟机热迁移。折腾了两周,最后发现技术上根本做不到。所以,选型时一定要想清楚自己的核心需求。

我的建议: 如果只有1-2个重度GPU用户,直通模式最省心。如果用户多、GPU少,还是考虑vGPU或者MIG吧。

好了,这一章就到这里。下一章我会讲vGPU的切分原理,那又是另一番天地了。