0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Intel Arc B580をQEMU/KVM上のWindows11で安定して動作させるに至るまでの苦心惨憺と凡ミス(長

Posted at

前提

これは大前提として, "トラブルの原因はQEMU/KVMの設定にはなかった" 話です.
この記事は, 飽く迄も筆者のやらかしを忘れず記憶に留めておくための備忘録です.
Intel Arc B580やQEMU/KVMの適切な動作設定等々については全く参考にならない話です.
以上を念頭に置いた上で読み進めてください.
結論だけを知りたい方は項目欄から "これはwwwwww重大なミスwwwwwwwwwwwww" という見出しまで飛んでください.

前環境

  • ホスト
  • OS:Debian12
  • CPU:AMD Ryzen9 7945HX(16C32T)
  • MEM:DDR5-5200 64GB
  • SSD:DRAM Cache付 NVMe1.4 SSD 4TB
  • iGPU:AMD Radeon 610M
  • dGPU:Intel Arc A380(6GB)
  • ゲスト
  • OS:Windows11 22H2
  • CPU:AMD EPYC(8C16T)
  • MEM:16GB
  • HDD:2TB
  • GPU0:VirtIO GPU DOD
  • GPU1:Intel Arc A380(6GB)

新環境

  • ホスト
  • OS:Debian12
  • CPU:AMD Ryzen9 7945HX(16C32T)
  • MEM:DDR5-5200 64GB
  • SSD:DRAM Cache付 NVMe1.4 SSD 4TB
  • iGPU:AMD Radeon 610M
  • dGPU:Intel Arc B580(12GB)
  • ゲスト
  • OS:Windows11 24H2
  • CPU:AMD EPYC-Milan(8C16T)
  • MEM:16GB
  • HDD:2TB
  • GPU0:VirtIO GPU DOD
  • GPU1:Intel Arc B580(12GB)

更新後の症状

  • 何もしていなくてもBSoD
  • 何かしても不明なタイミングでBSoD
  • Stop codeは"VIDEO TDR FAILURE"だが何も表示されずにVMがクラッシュすることもある
  • クラッシュするのは必ず"igdkmdnd64.sys"
  • ホストサーバーを巻き込んでのクラッシュはしない(他のVMに接続されている拡張カードのデータが多少ドロップする程度)

試したこと

  • ホストサーバーのUEFI/BIOSのアップデート -> 既に元々最新
  • ホストサーバーのOS(Debian12)のアップデート -> 他の拡張デバイスのデバイスIDが不可逆的に狂った(ダメージ・中)
  • Windows11のアップデート -> 24H2にアップデートしたが効果なし
  • B580 -> A380に切り戻し -> 効果なし
  • 最小構成にしてみる -> 効果なし
  • vfio.confのデバイスIDの変更漏れをやらかしてないかチェックする -> 問題なし
  • vfio.confのデバイスID変更後にアップデートしてないかチェックする -> 問題なし(というか、更新してもBSoDになる)

試行錯誤

効果:小

  • GRUBの起動パラメーターに"pcie_aspm=off"を入れる.
  • GRUBの起動パラメーターに"pci=realloc"を入れる.
  • /etc/modules-load.d/modules.conf に以下のパラメーターを追加する.
/etc/modules-load.d/modules.conf
vfio
vfio_iommu_type1
options kvm_amd avic=1

※"vfio_virqfd"はdmesgを見ているとどうも他のパラメーターにマージされているようなので, 先人の例ではよく記載するパターンがあるが, 省いてもきちんと動作するので問題はありません.

  • /etc/modprobe.d/kvm.conf に以下のパラメーターを追加する.
/etc/modprobe.d/kvm.conf
options kvm ignore_msrs=1
options kvm allow_unsage_assigned_interrupts=1
options kvm report_ignored_msrs=0
  • /etc/modprobe.d/qemu-system-x86.conf に以下のパラメーターを追加する.
/etc/modprobe.d/qemu-system-x86.conf
options kvm_intel nested=1
options kvm_amd avic=1
  • /etc/modprobe.d/vfio_iommu_type1.conf に以下のパラメーターを追加する.
/etc/modprobe.d/vfio_iommu_type1.conf
options vfio_iommu_type1 allow_unsage_interrupts=1
  • 仮想マシンのlibvirtで使用可能なhyperv関連の設定を全部載せする
    <hyperv mode="custom">
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
      <vpindex state="on"/>
      <runtime state="on"/>
      <synic state="on"/>
      <stimer state="on">
        <direct state="on"/>
      </stimer>
      <frequencies state="on"/>
      <tlbflush state="on"/>
      <ipi state="on"/>
      <avic state="on"/>
    </hyperv>

結果: テスト用ベンチマークの実行可能時間が僅かに伸びた(15秒前後->30秒前後).

効果:中(1)

  • 仮想マシンのGPUの接続トポロジをvirt-managerでパススルーデバイスを作成した場合のデフォルト設定である「PCI-to-PCIブリッジ配下」から(一番番号が若い)「PCIeルートポート直下」に変更する(virt-managerからxmlを編集).

ソース: https://wiki.gentoo.org/wiki/GPU_passthrough_with_virt-manager,_QEMU,_and_KVM
TroubleshootingAdjusting PCI Address of GPU inside Guest を参照

変更前

  <devices>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
    </hostdev>
  </devices>

変更後

  <devices>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x06" function="0x0"/>
    </hostdev>
  </devices>

結果: テスト用ベンチマークの実行可能時間が大抵の場合で大幅に伸びた(30秒前後->6分弱)

効果:中(2)

VMのXMLファイルに次のようなパラメーターを追加

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
    <qemu:arg value="name=opt/ovmf/X-PciMmio64Mb,string=65536"/>
    <qemu:arg value="-fw_cfg"/>
    <qemu:arg value="name=opt/ovmf/PciParseBar[0x05].BarType,string='PciBarTypePMem64'"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=4294967296"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=17179869184"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.pci-hole64-size=2199023255552"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.x-pci-hole64-fix=true"/>
    <qemu:env name="BAR" value="2"/>
</domain>

結果: ベンチマークを大分良いところまで走らせることは出来るが, 完走まで至らず.

効果:なし

次のようなスクリプトを作成して、libvirtの起動より前(パススルーデバイスがVMにバインドされる前)で実行

/usr/local/etc/rebar.sh
#!/bin/bash
echo -n "0000:03:00.0" > /sys/bus/pci/drivers/vfio-pci/unbind
echo 13 > /sys/bus/pci/devices/0000\:03\:00.0/resource2_resize
echo -n "8086 e20b" > /sys/bus/pci/drivers/vfio-pci/new_id
echo -n "0000:03:00.0" > /sys/bus/pci/drivers/vfio-pci/bind

結果: BARサイズが8GBに下がるとVMのWindowsにインストールされたIntelドライバはResizableBARが外れたと認識するためNG

効果:大

上述した"-fw_cfg"と"global"属性のqemuコマンドを削除し, pcie-root controllerに"pcihole64"ユニットを追加します.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
-   <controller type="pci" index="0" model="pcie-root">
+   <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">2147483648</pcihole64>
+   </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
  </qemu:commandline>
</domain>

結果: ベンチマークは1本単独なら完走できるが, 2週目を走らせると早々に(GPUが)リタイアする. -> 従前は1本完走することすら出来なかったので大幅な進歩(進歩なのか?)

ゴールを目指して

方向性

ここまでの(長時間のエンコード負荷をかけることでの)動作確認の傾向から, どうやら "pcihole64"それに関わりのありそうな何かの設定安定稼働の鍵 のようです.

しかし"pcihole64"に纏わる言及資料は少なく, そもそも論としてDebian12のQEMU/KVMにIntel dGPUでパススルー(しかもCPUがAMD)という変態環境なのがアカンのではないかという疑問も頭を過りますが, 後はlibvirtやQEMUに設定可能なパラメーターと睨めっこしつつ, トライアンドエラーの積み重ねです.

設定1

QEMUのUEFIのパラメーターを強制的に書き換えると言われている "Above 4G Decode" に関連するパラメーター "X-PciMmio" を再び追加してみます.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
      <pcihole64 unit="KiB">2147483648</pcihole64>
    </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
+   <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio64Mb,string=65536"/>
  </qemu:commandline>
</domain>

結果: ベンチマーク1本単独は完走できるが, 2本目を走らせると早々にGPUがリタイア.

これは効果の有無の判定が難しいですね. 可もなく不可でもない感じ.

設定2

QEMUのUEFIのパラメーターを強制的に書き換えると言われている "Above 4G Decode" に関連するパラメーター "X-PciMmio" の値を変更してみます. そもそもこの値は本当に反映されているのか? ゲストOSからは確認することが出来ないのだが.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio16384Mb,string=2097152"/>
  </qemu:commandline>
</domain>

結果: ベンチマーク1本目を走らせると早々にGPUがリタイア.

予想に反してあっさりとダウンしてしまいました. どうやらこの値はあまり弄ってはいけないようです.

設定3

"X-PciMmio" の値を(B580のBAR 0のサイズである)16MBに縮小変更してみます.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio16Mb,string=2097152"/>
  </qemu:commandline>
</domain>

結果: ベンチマーク1本目を走らせると40%を越える直前でGPUがリタイア(フォールト).

予想よりは持ち堪えましたがダメでした. デフォルトの64Mbに戻してみましょう(stringの方はpcihole64と同じ2048GB(2097152Mb)のままにします).

設定4

"X-PciMmio" の値を元の64Mbに戻してみます.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-fw_cfg"/>
+   <qemu:arg value="name=opt/ovmf/X-PciMmio64Mb,string=2097152"/>
  </qemu:commandline>
</domain>

結果: ベンチマーク1本目を走らせると73%を越える直前でGPUがリタイア(フォールト).

予想よりは持ち堪えましたがダメでした.
設定1に戻してもエンコードの長さ次第ではダメなので, どうやら "X-PciMmio" は "64Mb" と "65536" の組み合わせが最も良いようですが, 特に影響は無いか, あっても些少もしくは悪化する可能性があります.
取り敢えず"X-PciMmio"は省くことにしました(省いたら安定して1本目は通る).

設定5

"pcihole64" のサイズを16GiBに減らし, "-global" パラメーターへ "Above 4G Decode" に関する値を放り込みます.
閾値は2GBと6GBに設定しました.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">16777216</pcihole64>
    </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
+   <qemu:arg value="-global"/>
+   <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
+   <qemu:arg value="-global"/>
+   <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>

結果: ベンチマーク1本目で30秒以内にGPUがリタイア(フォールト).

一気に3つも設定変更をしてしまったのでどれが悪かったのか正直不明です.
(良いエンジニアの皆さんはそんなこと絶対にしてはいけません)

設定6

"pcihole64" のサイズを128GiBに増やします.
"Above 4G Decode" に関する値の閾値は前の設定と同じ2GBと6GBで続行します.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">134217728</pcihole64>
    </controller>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-cpu"/>
    <qemu:arg value="host,host-phys-bits=on,migratable=off,topoext=on,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff,kvm=off"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>

結果: なんと今まで(比較的)安定していたのに, エンコードを走らせる前の静止状態から突然のBSoDを起こしたためボッシュートです.

設定7

"pcihole64" のサイズを256GiBに増やします.
"-cpu" に関する値は取り去ってしまいます.
"Above 4G Decode" に関する値の閾値は前の設定と同じ2GBと6GBで続行します.
Grokくんのアドバイスで, featuresセクションに "ioapic driver="kvm"" を生やしました.
devicesセクションに "iommu" ユニットを生やしました.

<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
  (中略)
  <features>
  (中略)
+   <ioapic driver="kvm"/>
  </features>
  <devices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">268435456</pcihole64>
    </controller>
+   <iommu model="intel">
+     <driver caching_mode="on" iotlb="on" aw_bits="48"/>
+   </iommu>
  (中略)
  </devices>
  <qemu:commandline>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>

結果: エンコード速度が半分になり, かつ突然のBSoD.

設定8

featuresセクションにWindows向けの設定を再度盛り込んでみます.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
    <acpi/>
    <apic/>
+   <hyperv mode="custom">
+     <relaxed state="on"/>
+     <vapic state="on"/>
+     <spinlocks state="on" retries="8191"/>
+     <vpindex state="on"/>
+     <runtime state="on"/>
+     <synic state="on"/>
+     <stimer state="on">
+       <direct state="on"/>
+     </stimer>
+     <reset state="on"/>
+     <frequencies state="on"/>
+     <tlbflush state="on"/>
+     <ipi state="on"/>
+   </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
    <ioapic driver="kvm"/>
  </features>
  <deivices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
      <pcihole64 unit="KiB">268435456</pcihole64>
    </controller>
  (中略)
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <rom bar="on"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/>
    </hostdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
+     <driver iommu="on" ats="on"/>
    </memballoon>
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on" aw_bits="48"/>
    </iommu>
  </devices>
  <qemu:commandline>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>

結果: エンコード性能も振るわず, 割と早々に途中でGPUがリタイア(フォールト).

iommuセクションとhypervユニットを追加してからというもの, 性能も振るわず途中でGPUがリタイア(フォールト)するまでの時間も短くなってしまいました.

設定9

"pcihole64" の設定を2048GiBに戻し, "iommu" セクションのdriverユニットを必要最小限にしてみます.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
    <acpi/>
    <apic/>
    <hyperv mode="custom">
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
     <vpindex state="on"/>
      <runtime state="on"/>
      <synic state="on"/>
      <stimer state="on">
        <direct state="on"/>
      </stimer>
      <reset state="on"/>
      <frequencies state="on"/>
      <tlbflush state="on"/>
      <ipi state="on"/>
    </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
    <ioapic driver="kvm"/>
  </features>
  <deivices>
  (中略)
    <controller type="pci" index="0" model="pcie-root">
+     <pcihole64 unit="KiB">214783648</pcihole64>
    </controller>
  (中略)
    <hostdev mode="subsystem" type="pci" managed="yes">
      <driver name="vfio"/>
      <source>
        <address domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
      </source>
      <rom bar="on"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/>
    </hostdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
      <driver iommu="on" ats="on"/>
    </memballoon>
    <iommu model="intel">
+     <driver caching_mode="on"/>
    </iommu>
  </devices>
  <qemu:commandline>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.below-4g-mem-size=2147483648"/>
    <qemu:arg value="-global"/>
    <qemu:arg value="q35-pcihost.above-4g-mem-size=6442450944"/>
  </qemu:commandline>
</domain>

結果: 途中でGPUがリタイア(フォールト). 尚且つキャンセル直後にBSoD.

設定10

"iommu" セクションのdriverユニットを調整してみます.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
+   <ioapic driver="qemu"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
+     <driver intremap="on" caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>

結果: Windows自体が起動せず(延々とOSロード画面のままになる).

設定11

"iommu" セクションのdriverユニットを元に戻して, smmとmsrsを設定します. 取り敢えずリファレンス通りの48MiBを指定してみましょう(デフォルトは1,2,4,16MiBが設定されています).

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
+   <smm state="on">
+     <tseg unit="MiB">48</tseg>
+   </smm>
+   <ioapic driver="kvm"/>
+   <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
+     <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>

結果: ベンチマークを10%も進まずGPUがリタイア(フォールト).

設定12

smmを64MiBに設定します.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
    <smm state="on">
+     <tseg unit="MiB">64</tseg>
    </smm>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>

結果: ベンチマークを13%まで走らせたところでGPUがリタイア(フォールト).

設定13

smmを1024MiBに設定します.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
    <smm state="on">
+     <tseg unit="MiB">1024</tseg>
    </smm>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>

結果: ベンチマークを13%まで走らせたところでGPUがリタイア(フォールト).

これ以上smmのサイズを大きくする方向性にはあまり意味がないので, 小さくする(デフォルトサイズより少し大きいサイズから)方向で考えてみます.

設定14

smmを32MiBに設定します.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
    <smm state="on">
+     <tseg unit="MiB">32</tseg>
    </smm>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>

結果: ベンチマークを65%超えたところでGPUがリタイア(フォールト).

あまりsmmの値を弄っても良くならない気がします.

設定15

smmをonのみ(ゲストに通知されるサイズは1,2,4,16MiBのみ)に設定してみます.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
  <features>
  (中略)
-   <smm state="on">
-     <tseg unit="MiB">32</tseg>
-   </smm>
+   <smm state="on"/>
    <ioapic driver="kvm"/>
    <msrs unknown="ignore"/>
  </features>
  <deivices>
  (中略)
    <iommu model="intel">
      <driver caching_mode="on" iotlb="on"/>
    </iommu>
  </devices>
  (中略)
</domain>

結果: ベンチマークを59%超えたところでエンコーダーとGPU間の疎通がなくなりエンコード失敗.

設定16

  • 何故か消失していたOS情報の"metadata"記載を復活.
  • CPUの世代がこれより前になることは有り得ない(予定)なので"feature"を全部載せ.
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  (中略)
+ <metadata>
+   <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
+     <libosinfo:os id="http://microsoft.com/win/11"/>
+   </libosinfo:libosinfo>
+ </metadata>
  (中略)
+ <cpu mode="host-passthrough" check="none" migratable="off">
+   <topology sockets="1" dies="1" cores="16" threads="1"/>
+   <cache mode="passthrough"/>
+   <feature policy="require" name="x2apic"/>
+   <feature policy="require" name="tsc-deadline"/>
+   <feature policy="require" name="hypervisor"/>
+   <feature policy="require" name="tsc_adjust"/>
+   <feature policy="require" name="avx512f"/>
+   <feature policy="require" name="avx512dq"/>
+   <feature policy="require" name="avx512ifma"/>
+   <feature policy="require" name="avx512cd"/>
+   <feature policy="require" name="avx512bw"/>
+   <feature policy="require" name="avx512vl"/>
+   <feature policy="require" name="avx512vbmi"/>
+   <feature policy="require" name="avx512vbmi2"/>
+   <feature policy="require" name="gfni"/>
+   <feature policy="require" name="vaes"/>
+   <feature policy="require" name="vpclmulqdq"/>
+   <feature policy="require" name="avx512vnni"/>
+   <feature policy="require" name="avx512bitalg"/>
+   <feature policy="require" name="avx512-vpopcntdq"/>
+   <feature policy="require" name="spec-ctrl"/>
+   <feature policy="require" name="stibp"/>
+   <feature policy="require" name="arch-capabilities"/>
+   <feature policy="require" name="ssbd"/>
+   <feature policy="require" name="avx512-bf16"/>
+   <feature policy="require" name="cmp_legacy"/>
+   <feature policy="require" name="invtsc"/>
+   <feature policy="require" name="virt-ssbd"/>
+   <feature policy="require" name="lbrv"/>
+   <feature policy="require" name="tsc-scale"/>
+   <feature policy="require" name="vmcb-clean"/>
+   <feature policy="require" name="flushbyasid"/>
+   <feature policy="require" name="pause-filter"/>
+   <feature policy="require" name="pfthreshold"/>
+   <feature policy="require" name="vgif"/>
+   <feature policy="require" name="rdctl-no"/>
+   <feature policy="require" name="skip-l1dfl-vmentry"/>
+   <feature policy="require" name="mds-no"/>
+   <feature policy="require" name="pschange-mc-no"/>
+   <feature policy="disable" name="pcid"/>
+ </cpu>
  <deivices>
  (中略)
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
+     <driver iommu="on" ats="on"/>
    </memballoon>
+   <iommu model="intel">
+     <driver caching_mode="on" iotlb="on"/>
+   </iommu>
  </devices>
  (中略)
</domain>

結果: 2本目でBSoD

これはwwwwww重大なミスwwwwwwwwwwwww

ところで……

ここで筆者, 改めて足回り(ハードウェア)をチェックしていて, ある重大なやらかしに気付く.

このPC唯一のPCIe x16スロットは, 物理的には下図のように接続されている.

これらの内, Intel Arc B580と接続しているパーツだけPCIeリビジョンを書き出すと以下のようになる.

  • PCIe_x16スロット: PCIe5.0
  • PCIe_x16_to_PCIe_x8_and_M2_x2ライザーカード: PCIe4.0
  • PCIe_x16スロット_to_SFF8654ライザーカード: PCIe4.0
  • SFF8654toSFF8654ケーブル: PCIe3.0 <--!?!?!?!?!?!!?!?!!?!?!?!?!?!?
  • SFF8654toPCIe_x16ライザーカード: PCIe4.0
  • Intel_Arc_B580: PCIe4.0

お分かり頂けただろうか.

途中区間のケーブルだけ, PCIe3.0までの対応なのである.

詰まり, PCIe3.0(8GT/s x8)のSFF-8654ケーブルにPCIe4.0(16GT/s x8)の信号を流していたのである.

そりゃ通信エラーが起きてIntel Arc B580がフォールトするわけである.

そりゃ前の仮想化基盤サーバーでは上手く動いていたはずである(だってその仮想化基盤サーバーはPCIe3.0だったもの……).

というわけでUEFI/BIOSでPCIeの動作速度を3.0に落とします

UEFI/BIOSにPCIeの動作速度を設定する項目がありますので, 一律にPCIe3.0(設定出来る最低値) まで落とします.
(※SFF-8654ケーブルで「PCIe4.0に対応している」「入手性の良いもの」に行き当たらなかったため)

最終回答:

リンク速度をPCIe3.0にダウングレードする設定をしたら, どんなコマンドよりも有意に全てが安定しましたorz

何ならベンチマークを3スレッド同時に流しても快調に完走して次のベンチマークを走らせられます.

総括

  • そもそも論として, 相手(ハードウェアやドライバやソフトウェア)を疑うより, 自分で自分が作った環境の構成が本当に適切なのか疑え.
  • 自分の手元足元に先ず原因を求め, 1つ1つ虱潰しに可能性を消していった後に, 相手(ハードウェアやドライバやソフトウェア)を疑え.
  • トラブルの原因を最初に自分以外の他者に求めるのは甘え.
0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?