Archives de catégorie : Linux

GPU Passthrough Ryzen/Proxmox

L’objectif est double :

  1. Faire tourner correctement un Ryzen sur du Proxmox
  2. Assigner une carte graphique à une machine virtuelle Windows dit GPU passthrough afin de profiter des jeux vidéo.

Prérequis :

  • Deux carte graphique sont nécessaire pour faire la capture du bios de la carte graphique, par contre, pour son fonctionnellement, une seule est nécessaire
  • Un proxmox

Préparer les groupes IOMMU :

Modification dans /etc/default/grub :

GRUB_CMDLINE_LINUX_DEFAULT= »pcie_acs_override=downstream,multifunction video=efifb:off processor.max_cstate=1 intel_idle.max_cstate=0″

  • pcie_acs_override=downstream,multifunction pour aussi passer les cartes réseaux aux VMs.
  • video=efifb:off pour corriger un bug
  • processor.max_cstate=1 intel_idle.max_cstate=0 pour stabiliser certain freeze

Ensuite on met à jour grub :

update-grub
update-grub2

On reboot.

Carte Graphique :

On repère la carte graphique :

lspci -k
24:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Baffin [Radeon RX 460/560D / Pro 450/455/460/560] (rev cf)
Subsystem: PC Partner Limited / Sapphire Technology Baffin [Radeon RX 460]
Kernel driver in use: vfio-pci
Kernel modules: amdgpu
24:00.1 Audio device: Advanced Micro Devices, Inc. [AMD/ATI] Device aae0
Subsystem: PC Partner Limited / Sapphire Technology Device aae0
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
25:00.0 VGA compatible controller: NVIDIA Corporation GM206 [GeForce GTX 960] (rev a1)
Subsystem: Gigabyte Technology Co., Ltd GM206 [GeForce GTX 960]
Kernel driver in use: nouveau
Kernel modules: nvidiafb, nouveau
25:00.1 Audio device: NVIDIA Corporation Device 0fba (rev a1)
Subsystem: Gigabyte Technology Co., Ltd Device 36c1
Kernel driver in use: snd_hda_intel
Kernel modules: snd_hda_intel


On repère sa racine au niveau du bus PCI :

tree /sys/bus/pci |grep "24:00"
│   ├── 0000:24:00.0 -> ../../../devices/pci0000:00/0000:00:03.1/0000:24:00.0
│   ├── 0000:24:00.1 -> ../../../devices/pci0000:00/0000:00:03.1/0000:24:00.1
│   │   ├── 0000:24:00.0 -> ../../../../devices/pci0000:00/0000:00:03.1/0000:24:00.0
│   │   ├── 0000:24:00.1 -> ../../../../devices/pci0000:00/0000:00:03.1/0000:24:00.1

tree /sys/bus/pci |grep "25:00"
│   ├── 0000:25:00.0 -> ../../../devices/pci0000:00/0000:00:03.2/0000:25:00.0
│   ├── 0000:25:00.1 -> ../../../devices/pci0000:00/0000:00:03.2/0000:25:00.1
│   │   ├── 0000:25:00.0 -> ../../../../devices/pci0000:00/0000:00:03.2/0000:25:00.0
│   │   ├── 0000:25:00.1 -> ../../../../devices/pci0000:00/0000:00:03.2/0000:25:00.1

lspci -k
00:01.3 PCI bridge: Advanced Micro Devices, Inc. [AMD] Device 1453
Kernel driver in use: pcieport
Kernel modules: shpchp

Avant de libérer la carte du système, si le drapeau boot_vga est à 0, on peut récupèrer la ROM.

cat "/sys/devices/pci0000:00/0000:00:03.2/0000:25:00.0/boot_vga"
cat "/sys/devices/pci0000:00/0000:00:03.1/0000:24:00.0/boot_vga"

La ROM est nécéssaire si la carte graphique à passer à la machine virtuelle est sur le 1er slot.

Pour récuperer la ROM, la carte doit être obligatoirement sur le 2e slot PCIe (drapeau VGA à 0).

Pour récuperer la ROM :

cd /sys/bus/pci/devices/0000:25:00.0/
echo 1 > rom
cat rom > /usr/share/kvm/960GTX.bin
echo 0 > rom

On peux vérifier la validité de l’image avec rom-parser disponible sur github :

git clone https://github.com/awilliam/rom-parser
cd rom-parser
make
./rom-parser ../960GTX.bin
Valid ROM signature found @0h, PCIR offset 1a0h
PCIR: type 0 (x86 PC-AT), vendor: 10de, device: 1401, class: 030000
PCIR: revision 0, vendor revision: 1
Valid ROM signature found @f400h, PCIR offset 1ch
PCIR: type 3 (EFI), vendor: 10de, device: 1401, class: 030000
PCIR: revision 3, vendor revision: 0
EFI: Signature Valid, Subsystem: Boot, Machine: X64
Last image

  • On peut libèrer la carte et la racine :
echo "0000:25:00.0" > /sys/bus/pci/drivers/nouveau/unbind
echo "0000:25:00.1" > /sys/bus/pci/drivers/snd_hda_intel/unbind
echo "0000:00:03.1" > /sys/bus/pci/drivers/pcieport/unbind
  • (Recommandation Proxmox) On blackliste les drivers :
cat /etc/modprobe.d/blacklist.conf
blacklist radeon
blacklist nouveau
blacklist nvidia
blacklist amdgpu
blacklist snd_hda_intel
blacklist pcspkr
  • (Recommandation Proxmox) On passe les options vfio, tout sur la même ligne même les cartes réseaux. Si plusieurs lignes, c’est la dernière qui sera prise en compte, perso ça marche même sans :
cat /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:1401,10de:0fba,1002:67ef,1002:aae0 disable_vga=1

Modification de la machine virtuelle

  • Après avoir créé la machine virtuelle par le service web, on modifie le fichier situé dans /etc/pve/qemu-server/XXX.conf pour lui ajouter le disque dur en scsi et la carte graphique comme ci-dessous, j’ai remis la nvidia sur le slot 1 de la carte PCIe :
agent: 1
bios: ovmf
boot: dcn
bootdisk: virtio0
cores: 4
cpu: host
efidisk0: local:170/vm-170-disk-2.qcow2,size=128K
hostpci0: 24:00,pcie=1,x-vga=on,romfile=960GTX.bin
ide0: diskstation:iso/virtio-win-0.1.141.iso,media=cdrom,size=309208K
machine: q35
memory: 8192
name: WINDOWS10
net0: virtio=22:33:44:55:66:66,bridge=vmbr0
numa: 0
ostype: win10
virtio0: /dev/disk/by-id/ata-SanDisk_SDSSDA120G_1234567890123
scsihw: virtio-scsi-pci
smbios1: uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sockets: 1

Conclusion :

Recommandation pour Windows :

On installe :
  • les drivers virtio.
  • Synergy pour le partage de l’écran et de la souris.
  • Paramétrer l’accès au bureau à distance (mstsc)
  • GPU-Z toujours bon de voir comment ce qu’il y a dans la machine virtuelle.pour vérifier que la carte est bien en PCIe x16 3.0.
  • On passe une Nvidia de préférence pour jouer à l’aide de Moonlight (terrible!). Certain on peut-être déjà testé steam (moins bien) pour le game streaming.

Bref, il y a une « issue » en terme anglophone sur kvm/npt.

Sur Youtube, j’ai vu des performances monter à 110/120FPS avec la même carte graphique. ça manque un peu pour parler de performances natives sous Windows. Merci Geoff pour la résolution du bug npt. En attendant que le fix soit réellement appliqué dans le noyau, le lien du patch est https://patchwork.kernel.org/patch/10027525/

Garanti, le remote gaming, ça dépote.

Aides/Sources

https://pve.proxmox.com/wiki/Pci_passthrough

Plugin : check_ipfire_core_update

Depuis IpFire

Créer un script pour savoir si une mise à jour est disponible pour ipfire, par exemple copié collé dans /usr/lib/nagios/check_ipfire_core_update. Puis attribuer les droits d’exécution :

mkdir -p /usr/lib/nagios/
cat > /usr/lib/nagios/check_ipfire_core_update <<EOF
#!/bin/bash
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
STATE_DEPENDENT=4
SYSTEM=\`cat /opt/pakfire/db/lists/core-list.db |grep "core_"\`
PAKFIRE=\\\$core_release=\"\`cat /opt/pakfire/db/core/mine\`\"\;
if [[ \$SYSTEM == \$PAKFIRE ]]
then
echo \$STATE_OK
exit 0
else
echo \$STATE_CRITICAL
exit 2
fi
exit 3
EOF
chmod +x /usr/lib/nagios/check_ipfire_core_update

Ajouter la ligne suivante dans /etc/snmpd.conf et on relance le service snmpd

echo "extend update /usr/local/bin/check_ipfire_core_update" >> /etc/snmpd.conf
/etc/init.d/snmpd restart
 

Avant, sur Ipfire, on check l’OID.

snmpwalk -v2c -c public 127.0.0.1 nsExtendOutput1
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."update" = STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."echotest" = STRING: hello world
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."update" = STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."echotest" = STRING: hello world
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."update" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."echotest" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendResult."update" = INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendResult."echotest" = INTEGER: 0
snmptranslate -On NET-SNMP-EXTEND-MIB::nsExtendOutput1Line.\"update\"
.1.3.6.1.4.1.8072.1.3.2.3.1.1.6.117.112.100.97.116.101

Depuis le superviseur

Command à créer dans Eyes Of Network :

$USER1$/check_snmp -H $HOSTADDRESS$ -P 1 -C $USER2$ -o .1.3.6.1.4.1.8072.1.3.2.3.1.1.6.117.112.100.97.116.101 -l "Update" -s 0 -c 2

Ce qui donnerai dans un fichier texte normal

define command {
    command_name    check_ipfire_update
    command_line    $USER1$/check_snmp -H $HOSTADDRESS$ -P 1 -C $USER2$ -o .1.3.6.1.4.1.8072.1.3.2.3.1.1.6.117.112.100.97.116.101 -s 0 -c 2 -l "Update"
}