0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

そのiGPUのSR-IOV、実はちゃんと同時利用できてないかも? Proxmox + Intel i915/xe のVFスケジューリング設定

0
Last updated at Posted at 2026-08-21

Proxmoxで内蔵GPU(Intel i915/xe)をSR-IOVでVMから使う方法と重要なチューニング

この記事では以下の内容を記載します。重要なのは3つめです

  • 内蔵GPU(Intel i915/xe)をSR-IOVでVMから使う方法
  • 各VMから利用する方法
  • 各VMからiGPUを同時利用した際にVMごとfreezeした状態となる場合の重要なチューニング項目を記載します

前提条件

  • この記事ではPVE 9.2.10で動作確認を行っております。が、多分PVE 9.0, 9.1でも動作すると思われます。(って書くと確証が取れてないとAIに怒られるのですが、ここで離脱するのは勿体ないです)
  • iGPUがi915またはIris Xeが対象です。ご自分のハードウェアを良くご確認下さい。なお、この記事ではCore i7 1360Pで確認しております。

ProxmoxホストのiGPUをSR-IOVで仮想化して8つに分割する方法。

以下の手順に従ってインストールしてください。難しくありません。
https://github.com/strongtz/i915-sriov-dkms/blob/master/docs/install-pve-host.md
最後にlspciでVGA compatible controllerが8つ作られている(00:02.0~00:02.7までPF x 1 + VF x 7の合計8つ)ことを確認して下さい。

root@pve1:~# lspci -nnk -s 00:02
00:02.0 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        DeviceName: Onboard - Video
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: i915
        Kernel modules: i915, xe
00:02.1 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: i915
        Kernel modules: i915, xe
00:02.2 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: i915
        Kernel modules: i915, xe
00:02.3 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: i915
        Kernel modules: i915, xe
00:02.4 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: i915
        Kernel modules: i915, xe
00:02.5 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: i915
        Kernel modules: i915, xe
00:02.6 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: vfio-pci
        Kernel modules: i915, xe
00:02.7 VGA compatible controller [0300]: Intel Corporation Raptor Lake-P [Iris Xe Graphics] [8086:a7a0] (rev 04)
        Subsystem: Intel Corporation Device [8086:3037]
        Kernel driver in use: vfio-pci
        Kernel modules: i915, xe

各VMから利用する方法

ProxmoxダッシュボードからVMを通常通り作ります。Displayはdefaultのままでも構いません。
その後、Datacenter -> [PVE node] -> [VM ID] -> Hardware -> Add -> PCI Device
からiGPUのVFをVMに割り当てます。

  • Raw Device -> Device : ここで、上記00:02.1から00:02.7までのどれかを指定します。.0は指定しないでください。VMからは使えません。
  • All functions: OFF
  • Primary GPU: ここは任意ですがOFFの方がトラブルは少ないでしょう。
  • ROM-Bar: On
  • PCI-Express: On
    この状態でVMを起動します。

VMがLinuxの場合

以下のようにrenderD1xxが表示され、lspciにVGA compatible controllerとして、ホスト側のiGPUが見えていればOKです。

masa@jf:~$ ls -la /dev/dri/renderD128
crw-rw---- 1 root render 226, 128 Aug 21 15:41 /dev/dri/renderD128
masa@jf:~$ lspci| grep VGA
00:01.0 VGA compatible controller: Device 1234:1111 (rev 02)
01:00.0 VGA compatible controller: Intel Corporation Raptor Lake-P [Iris Xe Graphics] (rev 04)

この後は、GPUを何に使うかによって確認方法が異なります。

VMがWindows 11の場合

Device ManagerのDisplay adaptorsにIntel(R) Iris(R) Xe Graphicsと出ていれば問題ありません。もし黄色のアイコンで表示されていたら、ドライバをインストールしてあげて下さい。黄色のアイコンが消えるはずです。
image.png

重要なチューニング項目

ここからが本題です。上記までの手順でVFの割り当ては完了していますし、各VMを単体で動かしている限りは何の問題も起きません。問題が出るのは、複数のVMが同時にiGPUを使い始めた時です。

症状

私の環境では以下のように現れました。

  • Jellyfinを動かしているLinux VM(VF6)と、デスクトップ用途のWindows 11 VM(VF7)が同居している
  • Windows VM上のブラウザからJellyfinのダッシュボードを開き、Scan All Librariesを実行する
  • トランスコードとトリックプレイ生成が始まった瞬間から、Windows VMがフリーズしたような状態になる
  • マウスカーソルはカクカクとしか動かず、ウィンドウの描画も間に合わない
  • ジョブが終わると、何事もなかったかのように復帰する

厄介なのは、どこも壊れていないことです。Windows がクラッシュするわけでもドライバが落ちるわけでもなく、デバイスマネージャーは正常なままです。ホスト側のdmesgにもエラーは出ません。両方のVFは、それぞれ「正しく」動作しています。

この症状は、GPUの時分割の設定が初期状態のままであることが原因です(詳しくは後半の「原因」で説明します)。まずは直し方から書きます。

結果として私は、Jellyfinのスキャンだけは別のPC(Surface Pro 9)から実行する、という間の抜けた運用をしていました。同じことで悩んでいる方がいるのではないかと思います。

現在の値を確認する

ホスト側のsysfsで確認します。

ls /sys/class/drm/card0/

ここにprelim_iovというディレクトリがあるはずです。

root@pve1:~# ls /sys/class/drm/card0/
boot_display       card0-HDMI-A-1/    error              gt_max_freq_mhz    metrics/
card0-DP-1/        card0-HDMI-A-2/    gt/                gt_min_freq_mhz    power/
card0-DP-2/        dev                gt_act_freq_mhz    gt_RP0_freq_mhz    prelim_iov/
card0-DP-3/        device/            gt_boost_freq_mhz  gt_RP1_freq_mhz    subsystem/
card0-DP-4/        engine/            gt_cur_freq_mhz    gt_RPn_freq_mhz    uevent

VFごとの設定はこの下に並んでいます。

grep . /sys/class/drm/card0/prelim_iov/vf*/gt0/exec_quantum_ms
grep . /sys/class/drm/card0/prelim_iov/vf*/gt0/preempt_timeout_us

すべて0が返ってくるはずです。これが今回の犯人です。

ここが検索で見つからない理由

このパラメータ、名前が版によって異なります。上流のi915/Xeドライバでは iov/ 配下に execution_quantum_ms / preemption_timeout_us という名前で存在しますが、i915-sriov-dkmsでは prelim_iov/ 配下に exec_quantum_ms / preempt_timeout_us という短縮名で存在します。ディレクトリ名も属性名も一致しません。

「iov exec_quantum_ms」で検索しても上流の情報に辿り着けず、逆に上流の名前で検索しても自分の環境には存在しない、という状態になります。まずはlsご自分の環境の綴りを確認してください

設定する

まずは手で入れて効果を確かめるのが早いです。VF番号はご自分の環境に合わせてください(私の場合はVF6とVF7を使用しています)。

for vf in 6 7; do
  echo 8    > /sys/class/drm/card0/prelim_iov/vf$vf/gt0/exec_quantum_ms
  echo 8000 > /sys/class/drm/card0/prelim_iov/vf$vf/gt0/preempt_timeout_us
done

値の決め方

VFの切り替えには、最悪の場合 exec_quantum_ms + preempt_timeout_us の時間がかかります。デスクトップの体感を優先するなら、60Hzの1フレーム(約16.6ms)に収まる範囲が一つの目安になります。上記の 8ms + 8000us(=8ms) はここから決めた値です。

exec_quantum_ms は「そのVFが連続してGPUを握れる時間」、preempt_timeout_us は「譲るのを待つ時間」です。どちらも初期値は0(=無制限)になっています。

  • 短くする → 切り替えが細かくなりデスクトップは滑らかになりますが、コンテキストスイッチが増えてトランスコードのスループットは落ちます
  • 長くする → その逆です

参考までに、intel-gfxのメーリングリストではIntelのメンテナが切り分け手順としてexecution_quantum_ms = 20 / preemption_timeout_us = 20000を案内しています。デスクトップの応答性より全体のスループットを重視するなら、この20/20000側に寄せるのもありだと思います。

なお前述のRFCドキュメントには、リソースのプロビジョニングと異なりスケジューリングパラメータはVFドライバの動作中でも変更可能と書かれています。VMを止めずに値を振って比較できるはずです。

再起動後も維持する

sysfsの値は再起動で消えますので、/etc/sysfs.confに書いて永続化します。

ここで一つ注意点があります。/sys/class/drm/card0はシンボリックリンクなので、sysfsutilsが辿ってくれない可能性があります。実体パスで書くのが確実です。

readlink -f /sys/class/drm/card0

私の環境では以下のようになりました。

devices/pci0000:00/0000:00:02.0/sriov_numvfs = 7
devices/pci0000:00/0000:00:02.0/drm/card0/prelim_iov/vf6/gt0/exec_quantum_ms = 8
devices/pci0000:00/0000:00:02.0/drm/card0/prelim_iov/vf7/gt0/exec_quantum_ms = 8
devices/pci0000:00/0000:00:02.0/drm/card0/prelim_iov/vf6/gt0/preempt_timeout_us = 8000
devices/pci0000:00/0000:00:02.0/drm/card0/prelim_iov/vf7/gt0/preempt_timeout_us = 8000

/etc/sysfs.confは先頭の/sys/を落とした相対パスで書きます。sriov_numvfsの行を必ず先頭に置いてください。VFが生成されて初めてvf6/以下のパスが出現するため、順序が逆だと「そんなパスは無い」で失敗します。

設定が入ったか確認する

dmesgには出ません。sysfsutilsによる書き込みはカーネルログに残らないためです。sysfsを読み返して確認してください。

grep . /sys/class/drm/card0/prelim_iov/vf*/gt0/exec_quantum_ms
grep . /sys/class/drm/card0/prelim_iov/vf*/gt0/preempt_timeout_us

88000が返ってくれば成功です。0のままなら書き込みが失敗しているので、こちらに理由が出ているはずです。

systemctl status sysfsutils
journalctl -b -u sysfsutils

効果

冒頭に書いた症状、つまりWindows VM上からJellyfinのScan All Librariesを実行するとWindowsが固まる、という現象が解消しました。別PCから操作する必要がなくなり、素直に「Windows VMをデスクトップとして使う」運用に戻せています。

原因

SR-IOVが分割しているのはGPUへのアクセス権であって、処理能力ではありません。VFが7個あっても、その先にある物理的なエンジンは1セットです。

複数のVFから投げられたワークロードは、GPU内のマイクロコントローラであるGuC(Graphics microcontroller)によって時分割で処理されます。そしてその配分は、2つのパラメータで制御されています。

パラメータ 意味
execution quantum そのVFが連続してGPUを握っていられる時間
preemption timeout 量子を使い切ったVFが譲るのを待つ時間。超えたら強制的に取り上げる

問題は、**この2つの初期値がどちらも 0、つまり「無制限」**であることです。

この状態だと、先にGPUを掴んだVFは自分の仕事を投げ終わるまで手を離しませんし、譲るように促されても待ってもらえてしまいます。トランスコードのようなバッチ処理は延々とサブミットを続けるため、もう片方のVFはその間ずっと順番待ちになります。デスクトップの描画は数十ms待たされるだけで人間には「固まった」と見えるので、症状の出方とも一致します。

なお、この挙動はIntelが公開しているXeドライバ向けSR-IOVのRFCドキュメントにも記載があり、VFがGTを専有していない限り複数VFからのサブミットは時分割され、execution_quantumとpreemption_timeoutで制御されると明記されています。つまり仕様通りの動作であって、バグではありません。

なお、時分割の配分が適切になるだけで、GPUの処理能力そのものが増えるわけではありません。片方が本気でGPUを使い切っている間、もう片方の処理が遅くなること自体は変わりません。あくまで「順番が回ってこない」状態が解消される、という理解が正確かと思います。逆にコンテキストスイッチングでトータルには遅くなるはずですが、その間Windows VMがフリーズして使い物にならないよりはよっぽどましです。

まだ試していないが、効きそうな項目

正直に書いておくと、以下は私はまだ試していません。改善が十分だったため踏み込んでいないだけで、詰めるなら見るべき場所だと思います。

  • PF側にも同じ設定を入れるprelim_iov/pf/gt0/にも同じ属性があります。ホスト自身もGPUを使うため、ここが無制限のままだと片肺という見方ができます。前述のIntelメンテナの案内も、PFと全VFの両方に設定するよう書かれています
  • policies/engine_reset — 譲らないVFを強制的にリセットするポリシーです。保険として効く場面がありそうです

参考

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?