拯救我的 Galgame 和追番体验~

背景

前段时间买了台 MiniPC 装 PVE 作为 Homelab,打算作为媒体服务器 + NAS + 学习使用 (虽然最后主要是用来装 Windows 虚拟机玩 Galgame)

机子的 U 是 12 代的 i3-N305,买的时候 PVE8 还没发布,装的是 PVE7,5.x 的内核,对 12 代 U 还没有很完善的支持,核显无法使用。这就导致在 Jellyfin 看番只能软解,以及玩 Galgame 时压力都在 CPU 上,全程 CPU 100%,体验说不上好

最近发现 PVE8 发布了,升级到了 6.2 的内核,于是赶紧折腾一下。升级过程网上很多文章,这里略,无非就是配置下镜像源然后 apt update & apt dist-upgrade

开启核显 SR-IOV

SR-IOV 是一种硬件虚拟化技术,简单来说,能将物理 PCIe 设备虚拟成多个虚拟设备,在网卡上被广泛使用。Intel Core CPU 在 11 代后支持了该技术用于 GPU 虚拟化,替换了过去的 GVT-g(Intel 产品 GPU 虚拟化技术列表

开启 SR-IOV 主要用到这个驱动程序:i915-sriov-dkms,能够创建最多 7 个 VF(可以简单理解为 vGPU)

按着文档里「PVE Host Installation Steps (Tested Kernel 6.1 and 6.2)」这步做即可。在 update-grubupdate-initramfs -u 后多执行一句 pve-efiboot-tool refresh

但我这里遇到一个问题,重启后查看 dmesg | grep i915 有这样两条日志

i915: unknown parameter 'max_vfs' ignored
....
i915 0000:00:02.0: driver does not support SR-IOV configuration via sysfs

看了这个 issue 后,尝试重装。删除了原来的 dkms 模块,修改 dkms.conf 里的 PACKAGE_NAME 为 6.2(原来是 6.1,不过这步感觉应该没影响),然后 install 时加上 --force 重新走遍安装流程

这回正常了,上面两条日志没有了,也显示成功启用 VF,lspci | grep VGA 能看到多出来 7 个 GPU 设备,可以将其挂载到 LXC 或虚拟机中(00.02.0 那个物理 GPU / PF 不应该被使用)
lspci-output

Windows 虚拟机挂载

Windows 虚拟机要先配置好远程桌面,能连的上。虚拟机配置里「显示」选「无」(选「无」后就无法 VNC 连接了,所以要先配好远程桌面)

添加 PCI 设备,选择 vGPU,勾上主 GPU
win-vm-config

进入 Windows 安装驱动,Bingo
win-gpu

LXC 容器挂载

新建 LXC 容器要选择「嵌套」+「特权」(去掉无特权容器的 ✅)

挂载设备到 LXC 容器里,在 PVE 里找下对应设备驱动,选一个未使用的 vGPU 记下第 5 、 6 列的 video id 和 render id(不要选了 0 的物理 GPU / PF),我这里选择 card2 和 renderD130

$ ls -l /dev/dri
total 0
drwxr-xr-x 2 root root        320 Aug  6 00:38 by-path
crw-rw---- 1 root video  226,   0 Aug  6 00:30 card0
crw-rw---- 1 root video  226,   2 Aug  6 00:30 card2
crw-rw---- 1 root video  226,   3 Aug  6 00:30 card3
crw-rw---- 1 root video  226,   4 Aug  6 00:30 card4
crw-rw---- 1 root video  226,   5 Aug  6 00:30 card5
crw-rw---- 1 root video  226,   6 Aug  6 00:30 card6
crw-rw---- 1 root video  226,   7 Aug  6 00:30 card7
crw-rw---- 1 root render 226, 128 Aug  6 00:30 renderD128
crw-rw---- 1 root render 226, 130 Aug  6 00:30 renderD130
crw-rw---- 1 root render 226, 131 Aug  6 00:30 renderD131
crw-rw---- 1 root render 226, 132 Aug  6 00:30 renderD132
crw-rw---- 1 root render 226, 133 Aug  6 00:30 renderD133
crw-rw---- 1 root render 226, 134 Aug  6 00:30 renderD134
crw-rw---- 1 root render 226, 135 Aug  6 00:30 renderD135

关闭 LXC 容器,然后修改对应 LXC 容器配置文件

$ vim /etc/pve/lxc/<LXC_ID>.conf

添加以下内容把设备挂载到 LXC 内(分别填入 video id 和 render id,以及映射对应 card 和 render)

lxc.cgroup2.devices.allow: c 226:2 rwm
lxc.cgroup2.devices.allow: c 226:130 rwm
lxc.mount.entry: /dev/dri/card2 dev/dri/card0 none bind,optional,create=file
lxc.mount.entry: /dev/dri/renderD130 dev/dri/renderD128 none bind,optional,create=file
lxc-gpu-config

进入 LXC 容器安装驱动

$ apt update && apt install intel-media-va-driver-non-free vainfo

如果 LXC 内也使用了容器,例如我在 LXC 内装了 Docker 部署 Jellyfin,则容器内也要有驱动,并把设备挂载进去

$ docker run ... \
    ... \
    --device /dev/dri:/dev/dri \
    ...

然后 Jellyfin 容器内就可以找到对应设备,启用硬件加速即可
jellyfin-vaapi

总结

核心就两步:

  1. 在 host(PVE)上安装驱动模块,开启 SR-IOV
  2. 配置虚拟机 or LXC 挂载 vGPU,并在里面安装驱动

有了 GPU 后体验好了很多,无论是 Windows 玩 Galgame 还是 Jellyfin 追番硬解,CPU 压力基本不超 5%,十分流畅,释放了本就不强的 CPU 算力。而且相比独占的直通物理 GPU,SR-IOV 虚拟出来的多个 vGPU 能分给多台虚拟机使用,打造完美 Homelab