本文主要记录一类常见自托管场景:Unraid 宿主机使用 Intel UHD 770 核显,通过 SR-IOV 创建 VF,把 VF 直通给 Ubuntu 虚拟机,用于 VAAPI / QSV / FFmpeg 以及 Jellyfin / Plex 等媒体服务的硬件转码。命令与 PCI 地址以示例给出,部署时请按本机 lspci 结果替换。

需要注意的是:SR-IOV VF 更适合计算与转码,通常不适合当作物理 HDMI / DP 桌面输出。虚拟机主显示仍应保留 VNC / Virtio / QXL;核显 VF 只当渲染设备。

背景与适用范围

Unraid 宿主机
└── 00:02.0 = Intel UHD 770 PF(留给宿主机 i915)
    ├── 00:02.1 = VF → 可直通 VM 1
    ├── 00:02.2 = VF → 可直通 VM 2
    └── 00:02.x = 其他 VF

适用:

  • 宿主机是 Unraid,核显为 UHD 770(常见 PCI ID 8086:4680,以本机为准)。
  • 客机为较新的 Ubuntu(文中以 26.04 系内核为例),目标是转码,不是 passthrough 整卡做桌面。
  • 客机内最终需要稳定出现 /dev/dri/renderD128(编号以实际为准)。

不适用:

  • 希望虚拟机直接驱动主板 HDMI / DP 输出画面。
  • 把 PF(00:02.0)整卡直通给虚拟机,导致宿主机失去 iGPU 管理。

宿主机检查

识别核显与 VF

lspci -nnk | grep -A5 -Ei 'VGA|Display|Intel|4680'

成功创建 VF 后,常见形态是:

00:02.0 ... UHD Graphics 770 ... Kernel driver in use: i915
00:02.1 ... 同上 ... Kernel driver in use: vfio-pci
00:02.2 ... 同上 ... Kernel driver in use: vfio-pci

查看 VF 容量:

cat /sys/bus/pci/devices/0000:00:02.0/sriov_totalvfs
cat /sys/bus/pci/devices/0000:00:02.0/sriov_numvfs

sriov_totalvfs 不存在或为 0,写入 sriov_numvfs 失败,说明宿主机侧 i915 SR-IOV 链路尚未就绪。

配置要点

Unraid 上常见做法是使用 i915 SR-IOV 相关插件,安装带 SR-IOV 支持的 i915,并在启动时加载类似参数:

modprobe i915 enable_guc=3 max_vfs=7

实际创建几个 VF 由插件/配置决定。创建后确认:

lsmod | grep '^i915'
dmesg | grep -iE 'i915|guc|sriov|vf'
lspci -nnk -s 00:02.1

VF 理想状态是 Kernel driver in use: vfio-pci。若仍被 i915 占用,需要在 System Devices / VFIO 配置中勾选对应 VF,或走插件的绑定流程。

虚拟机配置

推荐:

建议
MachineQ35
BIOSOVMF
Primary DisplayVNC / Virtio / QXL(保留)
GPU添加 VF(如 00:02.1),不要选 PF 00:02.0
ROM BIOS留空
音频不必绑 iGPU 音频

hostdev 片段示意(function 对应 VF):

<hostdev mode='subsystem' type='pci' managed='yes'>
  <driver name='vfio'/>
  <source>
    <address domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
  </source>
</hostdev>

原则:一个 VF 只分配给一个 VM;转码设备与主显示分离。

客机:驱动与 grub

确认看到设备

lspci -nnk | grep -A6 -Ei 'VGA|Display|Intel|4680'

关注 Kernel driver in use:期望 i915。若是 xe 或未绑定,继续安装 SR-IOV 友好的 i915 与 blacklist。

安装 i915 SR-IOV DKMS(示例)

较新 Ubuntu 内核上,社区常见方案是 strongtz/i915-sriov-dkms(版本需匹配内核,以下版本号请按 release 页替换):

sudo apt update
sudo apt install -y build-essential dkms "linux-headers-$(uname -r)" wget curl pciutils

I915_SRIOV_VERSION="<version>"
wget -O "/tmp/i915-sriov-dkms_${I915_SRIOV_VERSION}_amd64.deb" \
  "https://github.com/strongtz/i915-sriov-dkms/releases/download/${I915_SRIOV_VERSION}/i915-sriov-dkms_${I915_SRIOV_VERSION}_amd64.deb"
sudo dpkg -i "/tmp/i915-sriov-dkms_${I915_SRIOV_VERSION}_amd64.deb"
dkms status | grep -i i915

若 DKMS 构建失败,先核对 uname -rlinux-headers 是否匹配、/lib/modules/$(uname -r)/build 是否存在。

Secure Boot:第三方 DKMS 在开启 Secure Boot 时可能无法加载。转码 VM 最简单的做法是关闭 Secure Boot;若必须开启,需要模块签名与 MOK,复杂度明显上升。

grub 参数

/etc/default/grubGRUB_CMDLINE_LINUX_DEFAULT 中追加:

i915.enable_guc=3 module_blacklist=xe
sudo update-grub
sudo update-initramfs -u
sudo reboot

含义:

  • i915.enable_guc=3:启用 GuC / HuC 相关能力,SR-IOV 场景通常需要。
  • module_blacklist=xe:避免 xe 抢占 Intel 核显 VF。

客机验证

PCI 与 DRI

lspci -nnk | grep -A6 -Ei 'VGA|Display|Intel|4680'
ls -l /dev/dri
dmesg | grep -iE 'i915|guc|huc|drm'

理想情况:

  • Kernel driver in use: i915Kernel modules 里出现 xe 可以接受)。
  • 存在 card0renderD128(编号以本机为准)。
  • dmesg 无 firmware / GuC 初始化失败。

转码主要使用 render 节点,例如 /dev/dri/renderD128

VAAPI 用户态

sudo apt update
sudo apt install -y vainfo intel-gpu-tools ffmpeg intel-media-va-driver-non-free

无桌面服务器不要裸跑 vainfo 依赖 X,应指定 DRM 设备:

vainfo --display drm --device /dev/dri/renderD128

正常时应能看到 Intel iHD 驱动与 H.264 / HEVC / VP9 等 profile 及 decode / encode 入口。若提示 can't connect to X server,在服务器上通常不是 VAAPI 不可用,改用上面的 DRM 方式即可。

FFmpeg 冒烟

VAAPI H.264:

ffmpeg -hide_banner \
  -init_hw_device vaapi=va:/dev/dri/renderD128 \
  -filter_hw_device va \
  -f lavfi -i testsrc2=size=1920x1080:rate=30 \
  -vf 'format=nv12,hwupload' \
  -c:v h264_vaapi \
  -frames:v 120 \
  -f null -

HEVC 将 -c:v 换成 hevc_vaapi 再测。QSV 示意:

ffmpeg -hide_banner \
  -init_hw_device qsv=hw:/dev/dri/renderD128 \
  -f lavfi -i testsrc2=size=1920x1080:rate=30 \
  -c:v h264_qsv \
  -frames:v 120 \
  -f null -

另开终端观察:

sudo intel_gpu_top
# 部分环境可试
sudo intel_gpu_top -d sriov

编码时应看到 Video / Render 类指标变化。VAAPI 成功而 QSV 失败时,优先以 VAAPI 作为生产转码路径;QSV 对 FFmpeg、oneVPL / MediaSDK 与设备枚举更敏感。

Docker 媒体服务映射

客机跑容器时需把 DRI 映射进去:

ls -l /dev/dri
getent group render
getent group video

Compose 示意:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    restart: unless-stopped
    devices:
      - /dev/dri:/dev/dri
    group_add:
      - "render"
      - "video"
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /path/to/media:/media
    ports:
      - "8096:8096"

服务内硬件加速优先选 VAAPI 或 Intel QuickSync,设备指向 /dev/dri/renderD128。权限不对时可先只映射 renderD128 做对照。

常见问题

现象优先检查
/dev/driVF 是否直通;DKMS 是否成功;是否被 xe 抢占;Secure Boot;内核与 DKMS 是否匹配
Kernel driver in use: xegrub 是否含 module_blacklist=xe,更新 grub/initramfs 后重启
vainfo 报 X server--display drm --device /dev/dri/renderD128
VAAPI 通、QSV 不通生产可只用 VAAPI
想 HDMI 出画面SR-IOV VF 通常不适合;改评估整卡直通或其他方案

注意事项

  1. 不要直通 PF。宿主机需要保留 00:02.0 上的 i915 管理面。
  2. PCI 地址、设备 ID、render 节点号因主板与内核而异,一律以本机 lspci / ls /dev/dri 为准。
  3. DKMS 版本与内核绑定;升级内核后要复查 dkms status 与转码冒烟。
  4. 文档中的版本号、插件名会随社区更新变化,以当前 release 与 Unraid 插件页为准。
  5. 生产变更前确认影响范围:改 grub、绑 VF、重启 VM 会中断正在进行的转码会话。

相关阅读

同系列还可对照:

来源

本文改写自 Octans 项目 usage 层 Unraid UHD 770 SR-IOV + Ubuntu 转码教程。路径与版本已做通用化;具体内核 / DKMS 组合以目标环境验证为准。