Le bug de réinitialisation GPU expliqué : pourquoi l’IOMMU ne suffit pas (et ce qui marche)

Cet article vous a aidé ?

Vous arrêtez une VM. Le GPU devrait revenir à l’hôte comme un boomerang bien dressé. À la place, il revient… mal.
Au démarrage suivant de la VM : écran noir. dmesg de l’hôte : « reset failed ». Votre autoscaler de cluster hausse les épaules et planifie le job sur un cadavre.

Si on vous a dit « activez IOMMU et tout ira bien », on vous a vendu une demi-vérité réconfortante. IOMMU apporte de l’isolation.
Il ne garantit pas la réinitialisation, la réinitialisation complète, ni que le périphérique reviendra d’un état atteint sous charge.
Voilà l’écosystème du bug de réinitialisation GPU : partie comportement du silicium, partie nuance du spec PCIe, partie réalité du pilote, et partie douleur opérateur.

Ce que l’on entend par « bug de réinitialisation GPU »

« Bug de réinitialisation GPU » n’est pas un bug unique. C’est un nom générique pour toute situation où un GPU ne peut pas être réinitialisé et réutilisé de manière fiable
sans redémarrage de l’hôte (ou cycle d’alimentation physique). Il apparaît le plus souvent dans ces scénarios :

  • VFIO GPU passthrough (KVM/QEMU/libvirt) où un GPU est attaché à une VM, puis détaché et réattaché.
  • Workloads GPU conteneurisés où le pilote hôte tente de récupérer d’un kernel hang ou d’un mauvais DMA.
  • Noeuds GPU multi-tenant avec MIG/SR-IOV/vGPU où les sémantiques de reset varient selon le mode et le firmware.
  • Tempêtes AER PCIe, fluctuations de lien, ou un GPU qui tombe dans un état basse consommation et ne revient pas proprement.

Le problème central est simple : un GPU n’est pas une NIC PCIe polie. C’est un SoC complexe avec plusieurs moteurs internes
(graphics, compute, copy, video, display), son propre firmware et une gestion d’énergie agressive. Quand vous « réinitialisez un périphérique PCIe »,
vous ne réinitialisez pas forcément tout cet état interne — ou vous le réinitialisez au mauvais moment, laissant le périphérique
à moitié vivant et perturbant le pilote au prochain bind.

Blague n°1 : les GPU ne « plantent » pas, ils entrent dans un état contemplatif où ils reconsidèrent leur relation avec votre pilote.

Faits intéressants et contexte historique (court, concret)

  1. PCIe FLR (Function Level Reset) est arrivé pour standardiser les resets par fonction, mais beaucoup d’implémentations initiales étaient partielles ou bizarres.
  2. Les GPU grand public étaient optimisés pour une seule instance d’OS par démarrage, bien avant que les utilisateurs de virtualisation n’exigent « detach/attach à l’infini ».
  3. L’étiquette « reset bug » d’AMD a pris de l’ampleur dans la communauté VFIO parce que certains modèles nécessitaient un reset du bus ou un cycle d’alimentation pour récupérer.
  4. La persistance de calcul de NVIDIA avait du sens pour le débit HPC, mais complique le comportement « teardown et rebind » quand on attend des resets propres.
  5. IOMMU a été conçu principalement pour le remappage DMA et la protection, pas comme gestionnaire de cycle de vie des périphériques.
  6. Les états d’alimentation PCIe comme D3hot/D3cold peuvent casser la réinitialisation quand le firmware/BIOS et l’OS ne s’accordent pas sur qui gère le réveil.
  7. ACS (Access Control Services) est devenu important parce que les plateformes grand public regroupent souvent plusieurs périphériques, empêchant un passthrough sûr.
  8. AER (Advanced Error Reporting) peut sauver pour le diagnostic, mais peut aussi inonder les logs quand un périphérique se comporte mal et dégrader la stabilité du nœud.

La conclusion inconfortable : « reset » n’est pas une chose unique. C’est une négociation entre le firmware plateforme, la topologie PCIe,
la capacité du périphérique et le comportement du pilote. Et les GPU sont les périphériques qui posent le plus de problèmes de négociation.

Pourquoi l’isolation IOMMU n’implique pas la récupérabilité

IOMMU est une garde-fou. Il mappe les adresses DMA du périphérique dans un domaine de traduction afin que les périphériques ne puissent pas griffonner la mémoire
physique arbitraire. Cela compte pour la sécurité et la stabilité. Cela permet aussi à VFIO d’assigner un périphérique à une VM en toute sécurité.

Mais IOMMU ne fait pas :

  • garantir que le périphérique peut être rendu dans un état propre au détachement
  • forcer le périphérique à honorer correctement FLR
  • réinitialiser l’état interne du firmware, les microcontrôleurs ou les rails d’alimentation
  • corriger une topologie PCIe cassée où le GPU partage un domaine de reset avec d’autres périphériques
  • vous protéger des attentes spécifiques des pilotes vendeurs sur l’ordre d’initialisation

En termes de production : IOMMU arrête un GPU incontrôlé de DMA-er votre hôte dans l’abîme. Il n’empêche pas le GPU d’être un appareil têtu qui refuse de redémarrer sans qu’on coupe son alimentation.

Les deux plans d’isolation à ne pas confondre

Les opérateurs les confondent parce qu’ils se ressemblent dans les schémas :

  • Isolation DMA (IOMMU) : « Ce périphérique peut-il accéder seulement à ce qu’on lui autorise ? »
  • Isolation du cycle de vie (domaine de reset) : « Peut-on réinitialiser et réinitialiser indépendamment ce périphérique ? »

Beaucoup de plateformes vous donnent la première et ratent silencieusement la seconde. C’est là que vit « IOMMU n’est pas suffisant ».

Domaines de reset : la dépendance cachée

Un GPU se trouve derrière un root port, peut-être derrière un switch, parfois derrière une puce PLX, parfois en partageant des lanes avec d’autres périphériques.
Même si le GPU est dans son propre groupe IOMMU, il peut partager une ligne de reset ou un domaine d’alimentation avec autre chose.
Quand vous émettez un bus reset vous pouvez réinitialiser des voisins. Quand vous émettez FLR le GPU peut l’ignorer.
Quand vous n’émettez rien, le pilote essaie un « soft reset » des moteurs internes et parfois échoue.

Si vous exécutez des workloads multi-tenant, vous devriez traiter « reset indépendant » comme une exigence d’approvisionnement, pas comme une réflexion après coup.
C’est là que des choix matériels ennuyeux battent des flags kernel malins.

Une citation (idée paraphrasée)

Idée paraphrasée : l’espoir n’est pas une stratégie — concevez des systèmes pour que la défaillance soit attendue et la récupération routinière. — Gene Kranz (leader opérations, programme Apollo)

Mécanismes de reset PCIe : FLR, bus reset, hot reset, et pourquoi les GPU sont particuliers

Function Level Reset (FLR)

FLR est le plus propre conceptuellement : réinitialiser juste une fonction PCIe (comme 0000:65:00.0) sans pulvériser tout le bus.
L’OS peut le demander via sysfs, et VFIO l’utilise quand il est disponible.

Réalité : certains GPU implémentent FLR d’une manière qui réinitialise l’espace de configuration mais pas l’état interne du firmware qui vous importe réellement.
Ou FLR ne fonctionne que lorsque le périphérique est dans un certain état d’alimentation. Ou il « marche » et le périphérique revient avec des moteurs bloqués.

Bus reset / secondary bus reset

Cela réinitialise un segment de bus en aval. Plus forcé que FLR. Plus de dégâts collatéraux aussi.
Si votre GPU est derrière un bridge ou un switch PCIe, un bus reset peut parfois le forcer à se conformer.

L’inconvénient est évident : vous pouvez réinitialiser d’autres endpoints derrière le même bridge. Si vous avez de la chance, ce n’est rien d’important.
Si vous n’en avez pas, vous venez de redémarrer votre HBA de stockage en plein pic I/O. Bon courage pour expliquer ce graphe à la finance.

Hot reset

Le hot reset se rapproche de « simuler unplug/replug au niveau du lien ». Il peut fonctionner quand FLR échoue.
Il peut aussi échouer si la plateforme ne peut pas réentraîner correctement le lien ou si le firmware du périphérique se bloque pendant le link training.

Reset fondamental / cycle d’alimentation

L’option nucléaire. Si le GPU ne revient pas sans coupure d’alimentation, vous n’avez pas un problème de reset logiciel.
Vous avez un problème de cycle de vie plateforme. En datacenter vous résolvez cela avec :

  • nœuds avec contrôle d’alimentation du slot PCIe via BMC (rare, mais précieux)
  • partitions GPU qui tolèrent les redémarrages de nœuds
  • garder des workloads redémarrables et concevoir l’ordonnancement autour des défaillances

Pourquoi les GPU sont particuliers (et agaçants)

Les GPU ont plusieurs « sous-périphériques » internes derrière une seule fonction PCIe : copy engines, contrôleurs mémoire,
moteurs vidéo, moteurs d’affichage, processeurs de sécurité, et une grosse portion de firmware qui initialise le tout. Un reset qui ne
réinitialise pas le firmware et l’état du contrôleur mémoire est un reset de nom seulement.

Ajoutez la gestion d’alimentation : les GPU descendent agressivement en modes basse consommation quand ils sont inactifs. Si vous détachez un GPU pendant qu’il entre
dans un état de basse consommation profond (ou pendant que runtime PM est actif), vous pouvez obtenir un périphérique qui s’énumère mais ne répond pas correctement.

Modes de défaillance que vous verrez en production

1) « reset failed » après l’arrêt d’une VM ; le prochain attach bloque

Symptomatique VFIO classique : la VM fonctionne. Vous l’arrêtez. Détachez le GPU. Réattachez à une autre VM. Libvirt dit que ça a marché.
Le guest boote sur une console noire. Les logs de l’hôte montrent un reset échoué, ou le pilote refuse de se binder.

2) GPU bloqué en D3cold (ou alternance d’états d’alimentation)

Le périphérique apparaît dans lspci mais ne s’initialise pas. Parfois les logs kernel mentionnent « unable to change power state ».
C’est souvent une interaction avec le runtime power management : le kernel tente de suspendre le périphérique, puis vous tentez de le réinitialiser, et ça devient le bazar.

3) Spam AER, resets de lien, et nœuds « gelés »

Le GPU commence à produire des erreurs PCIe correctables/non-fatales. AER inonde dmesg. Le CPU consomme du temps dans le traitement d’interruptions.
Même si les workloads continuent, le profil de latence du nœud devient peu fiable.

4) Le pilote pense que le GPU est occupé pour toujours

Le pilote kernel tente de quiescer le périphérique, mais les moteurs internes sont bloqués. Il attend des fences qui ne se signalent jamais.
Vous essayez de décharger le module et cela bloque. Ce n’est pas « un bug de pilote » dans le sens moral ; c’est le pilote qui fait la seule chose sûre :
refuser de prétendre que le matériel est OK.

5) Surprises multi-fonctions : fonction audio, contrôleur USB-C, etc.

Beaucoup de GPU exposent plusieurs fonctions (graphics + HDMI audio + contrôleur USB pour VirtualLink/USB-C).
Réinitialiser une fonction sans les autres (ou binder de façon inconsistante) peut laisser le périphérique dans un état incohérent.

6) Défaillances « ça marchait le matin »

Sous de faibles charges de test tout se réinitialise proprement. Sous calcul soutenu plus cycles fréquents detach/attach, les resets se dégradent.
C’est courant quand le firmware entre dans un état moins testé après longue exécution, ou quand la mémoire GPU est fortement utilisée et que les chemins de teardown
ne sont pas parfaits.

Feuille de route pour un diagnostic rapide

C’est la version à exécuter quand le pager sonne et que vous ne voulez pas devenir archéologue PCIe.
L’objectif : identifier si vous avez un problème de capacité de reset, un problème de gestion d’alimentation,
un problème de binding de pilote ou un problème de topologie/domaine de reset.

Première étape : confirmez ce qui a échoué — reset, bind ou lien

  • Vérifiez dmesg pour « reset failed », « AER », « link down », « device not ready ».
  • Vérifiez la disponibilité des méthodes de reset dans sysfs pour la fonction PCIe.
  • Vérifiez si le périphérique est en D3cold/D3hot.

Deuxième étape : validez la topologie et les risques de domaine de reset

  • Trouvez le bridge/root port en amont et voyez ce qui d’autre le partage.
  • Confirmez l’appartenance aux groupes IOMMU, mais n’en restez pas là.
  • Cherchez un switch/bridge PCIe qui pourrait être la vraie cible du reset.

Troisième étape : choisissez l’action de récupération la moins destructive

  1. Tentez le reset de fonction (FLR) si disponible.
  2. Tentez un cycle unbind/bind (si le pilote supporte une réinitialisation propre).
  3. Tentez hot reset ou secondary bus reset si le GPU est isolé derrière son propre bridge/switch.
  4. Si les erreurs persistent ou que des tempêtes AER commencent : vider le nœud, redémarrer l’hôte.

Si vous ne pouvez pas récupérer sans redémarrage plus qu’occasionnellement, arrêtez de traiter ça comme une « erreur opérateur ».
C’est une contrainte architecturale. Construisez l’ordonnancement et la maintenance autour de cela.

Tâches pratiques : commandes, sorties, décisions (12+)

Tous les exemples supposent un hôte Linux avec root et un GPU à 0000:65:00.0.
Remplacez les adresses et noms de pilotes selon le cas.

Task 1: Identify the GPU and functions (are you missing the audio/USB function?)

cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|nvidia|amd|audio|usb'
65:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2231] (rev a1)
65:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:1aef] (rev a1)

Ce que cela signifie : Votre « GPU » comprend au moins deux fonctions. Les plans de passthrough/reset doivent prendre en compte les deux.
Décision : Si vous passez 65:00.0 en passthrough, pensez aussi à 65:00.1 pour garder la cohérence du périphérique, ou liez-le explicitement à un pilote sûr.

Task 2: Check IOMMU is actually enabled (don’t assume)

cr0x@server:~$ dmesg | egrep -i 'iommu|dmarmr|intel-iommu|amd-vi' | head
[    0.912345] DMAR: IOMMU enabled
[    0.912678] DMAR: Host address width 46

Ce que cela signifie : Le kernel croit que IOMMU est activé.
Décision : Si vous ne voyez pas cela, corrigez d’abord les paramètres de boot/BIOS ; la stabilité VFIO sans IOMMU est une chimère.

Task 3: Inspect IOMMU group membership (necessary, not sufficient)

cr0x@server:~$ gpu=0000:65:00.0; group=$(readlink /sys/bus/pci/devices/$gpu/iommu_group); echo $group; ls -l $group/devices
../../kernel/iommu_groups/42
total 0
lrwxrwxrwx 1 root root 0 Feb  4 10:01 0000:65:00.0 -> ../../../../devices/pci0000:60/0000:60:01.0/0000:65:00.0
lrwxrwxrwx 1 root root 0 Feb  4 10:01 0000:65:00.1 -> ../../../../devices/pci0000:60/0000:60:01.0/0000:65:00.1

Ce que cela signifie : Les fonctions GPU partagent le même groupe IOMMU, ce qui est normal.
Décision : Si des périphériques non liés sont dans le groupe, vous ne pouvez pas faire de passthrough en toute sécurité sans changements plateforme (ou en acceptant le risque).

Task 4: Find the upstream bridge/root port (reset domain clue)

cr0x@server:~$ gpu=0000:65:00.0; echo "GPU path:"; readlink -f /sys/bus/pci/devices/$gpu
GPU path:
/sys/devices/pci0000:60/0000:60:01.0/0000:65:00.0

Ce que cela signifie : Le port en amont est 0000:60:01.0.
Décision : Vérifiez ce qui d’autre se trouve derrière 60:01.0. Si c’est un switch partagé, un bus reset peut avoir des dommages collatéraux.

Task 5: List everything behind the same upstream port

cr0x@server:~$ upstream=0000:60:01.0; find /sys/bus/pci/devices/$upstream/ -maxdepth 2 -name '0000:*' -printf '%f\n'
0000:65:00.0
0000:65:00.1

Ce que cela signifie : Seules les fonctions GPU vivent derrière ce port.
Décision : Un bus reset sur le segment descendant est probablement sans danger (validez quand même qu’il n’y a pas de switch caché avec d’autres ports).

Task 6: Check whether the kernel thinks FLR is available

cr0x@server:~$ gpu=0000:65:00.0; lspci -s ${gpu#0000:} -vv | egrep -i 'Capabilities:.*FLR|Reset'
Capabilities: [1b0] Vendor Specific Information: Len=14

Ce que cela signifie : Cette sortie ne prouve pas le support FLR ; certains périphériques ne l’annoncent pas proprement dans un grep amical.
Décision : Utilisez sysfs ensuite ; ne vous fiez pas aux listings marketing des capacités.

Task 7: Try sysfs function reset (the least destructive)

cr0x@server:~$ gpu=0000:65:00.0; sudo sh -c "echo 1 > /sys/bus/pci/devices/$gpu/reset"
sh: 1: cannot create /sys/bus/pci/devices/0000:65:00.0/reset: Permission denied

Ce que cela signifie : Vous avez oublié d’être root (ou votre redirection de shell n’était pas privilégiée).
Décision : Utilisez un shell root ou sudo tee pour écrire dans sysfs.

cr0x@server:~$ gpu=0000:65:00.0; echo 1 | sudo tee /sys/bus/pci/devices/$gpu/reset
1

Ce que cela signifie : Le kernel a accepté une demande de reset.
Décision : Vérifiez immédiatement dmesg pour succès/échec ; l’acceptation ne signifie pas l’achèvement.

Task 8: Confirm reset outcome in dmesg (success vs “reset failed”)

cr0x@server:~$ dmesg -T | tail -n 20
[Sun Feb  4 10:05:01 2026] pci 0000:65:00.0: resetting
[Sun Feb  4 10:05:02 2026] pci 0000:65:00.0: reset failed

Ce que cela signifie : La plateforme/le périphérique n’a pas pu compléter le chemin de reset demandé.
Décision : Passez au hot reset / bus reset seulement si le GPU est isolé derrière son propre bridge ; sinon videz et redémarrez le nœud.

Task 9: Check power state (D0 vs D3) to catch runtime PM traps

cr0x@server:~$ gpu=0000:65:00.0; cat /sys/bus/pci/devices/$gpu/power_state
D3cold

Ce que cela signifie : Le périphérique est en profonde mise hors tension.
Décision : Envisagez de désactiver le runtime PM pour le périphérique, ou assurez-vous qu’il est en D0 avant les opérations detach/reset.

Task 10: Disable runtime power management for the GPU (test change)

cr0x@server:~$ gpu=0000:65:00.0; echo on | sudo tee /sys/bus/pci/devices/$gpu/power/control
on

Ce que cela signifie : Le runtime PM est forcé « on » (pas d’autosuspend) pour cette fonction.
Décision : Retestez les cycles detach/attach. Si la stabilité s’améliore, rendez-le persistant via une règle udev ou une unité systemd (avec précaution).

Task 11: Unbind from current driver (prepare for rebinding or VFIO)

cr0x@server:~$ gpu=0000:65:00.0; readlink /sys/bus/pci/devices/$gpu/driver
../../../../bus/pci/drivers/nvidia
cr0x@server:~$ gpu=0000:65:00.0; echo $gpu | sudo tee /sys/bus/pci/drivers/nvidia/unbind
0000:65:00.0

Ce que cela signifie : Le périphérique est détaché du driver nvidia.
Décision : Si l’unbind bloque ou renvoie des erreurs, le pilote peut être bloqué en attente du matériel ; vider et redémarrer est souvent la seule échappatoire propre.

Task 12: Bind to vfio-pci (for passthrough) and verify binding

cr0x@server:~$ gpu=0000:65:00.0; sudo modprobe vfio-pci
cr0x@server:~$ gpu=0000:65:00.0; vendor=$(cat /sys/bus/pci/devices/$gpu/vendor); device=$(cat /sys/bus/pci/devices/$gpu/device); echo $vendor $device
0x10de 0x2231
cr0x@server:~$ echo 10de 2231 | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
10de 2231
cr0x@server:~$ gpu=0000:65:00.0; readlink /sys/bus/pci/devices/$gpu/driver
../../../../bus/pci/drivers/vfio-pci

Ce que cela signifie : vfio-pci possède maintenant le périphérique.
Décision : Si le binding échoue ou revient en arrière, vous avez des pilotes concurrents (initramfs, règles udev ou Xorg) qui réclament le GPU.

Task 13: Check for AER errors that predict future resets failing

cr0x@server:~$ dmesg -T | egrep -i 'AER|pcieport|error' | tail -n 15
[Sun Feb  4 10:06:10 2026] pcieport 0000:60:01.0: AER: Corrected error received: 0000:60:01.0
[Sun Feb  4 10:06:10 2026] pcieport 0000:60:01.0: AER: PCIe Bus Error: severity=Corrected, type=Physical Layer

Ce que cela signifie : Il existe des problèmes au niveau du lien même si le GPU « marche ».
Décision : Traitez les AER persistants comme un problème matériel/plateforme : vérifiez l’assise, les risers, le câblage (pour PCIe externe), les réglages BIOS, ou remplacez le nœud.

Task 14: Verify link speed/width (degraded links correlate with weird resets)

cr0x@server:~$ gpu=0000:65:00.0; sudo lspci -s ${gpu#0000:} -vv | egrep -i 'LnkSta:|LnkCap:'
LnkCap: Port #0, Speed 16GT/s, Width x16
LnkSta: Speed 8GT/s (downgraded), Width x8 (downgraded)

Ce que cela signifie : Votre GPU fonctionne sur un lien dégradé.
Décision : Corrigez d’abord les problèmes physiques/topologiques. Déboguer des resets sur un lien dégradé revient à déboguer le stockage sur un câble SATA moribond : vous n’apprendrez rien d’utile.

Task 15: Try a downstream bus reset only if topology is safe

cr0x@server:~$ upstream=0000:60:01.0; echo 1 | sudo tee /sys/bus/pci/devices/$upstream/reset
1

Ce que cela signifie : Vous avez demandé un reset sur le port/bridge en amont, qui peut réinitialiser le segment descendant.
Décision : Si d’autres périphériques partagent ce segment, ne faites pas cela sur un nœud en production. Si le GPU est isolé, cela peut restaurer un périphérique « coincé ».

Task 16: Validate device is responsive post-reset (quick health signal)

cr0x@server:~$ gpu=0000:65:00.0; lspci -s ${gpu#0000:} -nn
65:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2231] (rev a1)

Ce que cela signifie : Le périphérique s’énumère toujours, ce qui est le minimum indispensable.
Décision : S’il disparaît entièrement, vous êtes en territoire de link training/domaine d’alimentation ; prévoyez un redémarrage de l’hôte et enquêtez sur le firmware plateforme.

Ce qui fonctionne : stratégies d’atténuation qui tiennent en conditions réelles

1) Préférez les GPU et plateformes avec comportement de reset éprouvé

Ce n’est pas philosophique. C’est opérationnel. Si vous avez besoin de réaffectations fréquentes (VFIO multi-tenant, fermes CI, VM GPU éphémères),
votre matériel doit supporter un FLR fiable ou un bus reset prévisible sans dommages collatéraux.

Les GPU et serveurs de classe datacenter ont tendance à mieux se comporter car ils sont conçus pour les opérations en flotte et la récupération distante.
Les plateformes grand public peuvent fonctionner, mais vous vous engagez dans un passe-temps impliquant paramètres kernel, contournements ACPI et redémarrages occasionnels.

2) Gardez le GPU lié à un seul « monde » aussi longtemps que possible

Chaque detach/attach est une chance de tomber sur le mauvais chemin. Si vous pouvez planifier « le GPU reste avec une VM pour sa durée de vie », faites-le.
Si vous pouvez pinner le GPU sur un nœud et déplacer les jobs plutôt que les GPUs, faites-le. Si vous pouvez éviter VFIO et utiliser des conteneurs sur l’hôte,
faites-le (si vous faites confiance au modèle multi-tenant et avez des contrôles d’isolation).

3) Désactivez le runtime PM pour les GPUs en passthrough (sélectivement)

Le runtime PM économise des watts. Il introduit aussi des états qui rendent le reset/rebind plus difficile. Pour les GPUs en passthrough, la fiabilité prime sur l’élégance.
Forcez D0 pendant les transitions de cycle de vie, ou désactivez le runtime PM pour le périphérique entièrement.

4) Traitez « reset failed » comme une défaillance de santé du nœud, pas comme un incident isolé

Si un GPU ne peut pas être réinitialisé une fois, il est plus probable qu’il échoue de nouveau dans des conditions similaires. Marquez le nœud comme non sain, videz les workloads,
et redémarrez selon votre calendrier, pas en période de pointe.

5) Utilisez une échelle de reset contrôlée

Ne passez pas directement aux bus resets. Utilisez des tentatives progressives :

  1. Assurez-vous qu’aucun processus n’utilise le GPU (ou arrêtez la VM proprement).
  2. Détachez le pilote (hôte) ou détachez le périphérique (VFIO).
  3. Tentez FLR via sysfs.
  4. Tentez hot/bus reset uniquement si l’isolation est confirmée.
  5. Si toujours cassé : redémarrez le nœud ; si récurrent : changez le firmware/plateforme.

6) Alignez les paramètres firmware/BIOS avec vos attentes de reset

Le BIOS/UEFI peut vous saboter avec la gestion d’alimentation et des fonctionnalités PCIe. Améliorations courantes (dépendant de la plateforme) :

  • Désactiver les états PCIe profonds pour le slot si vous voyez des problèmes D3cold.
  • Garder Above 4G Decoding activé pour les grands BAR et GPUs modernes.
  • Mettre à jour le VBIOS GPU et le BIOS système ensemble ; des générations dépareillées créent un comportement « marche jusqu’à ce que ça casse ».

7) Pour les clusters : intégrez la tolérance au redémarrage et profitez-en

Si votre flotte est assez grande, la réponse économiquement correcte est souvent : acceptez que certains resets GPU nécessitent des redémarrages,
et faites du redémarrage de nœud une remédiation normale avec un ordonnancement de jobs rapide.

Blague n°2 : Le reset GPU le plus fiable est celui effectué par une alimentation qui « oublie » brièvement qu’elle fournissait du courant.

Trois mini-récits du monde de l’entreprise

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Une entreprise SaaS de taille moyenne a construit un service d’inférence avec GPU. Ils voulaient une forte isolation des locataires, donc ils ont utilisé VFIO passthrough :
une VM par charge client, GPUs réassignés au fur et à mesure que les VMs tournaient. L’équipe plateforme a activé IOMMU, validé les groupes IOMMU, et écrit
de l’automatisation qui détachait et réattachait les périphériques entre VMs.

Ça a passé le staging. Ça a passé les tests de charge. Le déploiement a commencé discrètement et semblait correct pendant quelques jours, ce qui est exactement la façon dont
des bugs plateforme gagnent la confiance avant de la dépenser.

Le premier incident a commencé par « quelques jobs bloqués ». Puis c’est devenu « la moitié des GPUs ne sont plus ordonnancés ». Les VMs étaient saines.
Libvirt rapportait des detach/attach réussis. Mais les périphériques GPU ne s’initialisaient pas dans la VM suivante après un detach.
Les opérateurs ont trouvé « reset failed » dans dmesg et ont vu des opérations unbind se bloquer. Quelques nœuds ont commencé à logger des erreurs PCIe corrigées
qui se sont lentement transformées en tempêtes.

La mauvaise hypothèse était simple : « IOMMU groups impliquent une réutilisation sûre. » L’isolation était correcte. La récupérabilité ne l’était pas.
Les modèles GPU de leur flotte pouvaient être passés en passthrough correctement, mais leur comportement de reset était peu fiable sous churn répété.
Ils n’étaient pas inutilisables pour un usage desktop ; ils n’étaient simplement pas conçus pour ce cycle de vie.

La correction a été opérationnelle et architecturale : ils ont arrêté de réutiliser les GPUs entre la durée de vie des VMs. Un GPU restait épinglé à une VM jusqu’à
ce que la VM soit détruite, et les nœuds étaient redémarrés pendant une fenêtre de maintenance contrôlée avant de revenir dans le pool.
La planification de capacité est devenue un peu plus honnête. Les incidents ont chuté fortement.

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Un shop d’analytics financier exécutait des workloads intensifs la nuit. Ils ont voulu réduire les coûts d’énergie et ont activé une gestion runtime PM agressive.
L’idée était raisonnable : les GPUs sont inactifs entre les rafales, les autosuspendre économise des watts.

Deux semaines plus tard, ils ont eu une nouvelle classe de défaillance : des nœuds qui semblaient sains mais refusaient de lancer des jobs GPU après une période d’inactivité.
L’ordonnanceur assignait un job, le job échouait à ouvrir le périphérique, les retries rebondissaient entre les nœuds, et finalement
le cluster paraissait « occupé » tout en faisant presque rien. Une illusion de montée en charge classique.

La cause racine était que les GPUs entraient dans des états de basse consommation profonds qui interagissaient mal avec la réinitialisation du pilote après de longues inactivités.
Le chemin de reset fonctionnait parfois, parfois pas. Le taux d’échec était faible, mais le rayon d’impact opérationnel était élevé car cela déclenchait des essaims de retries.

Ils ont désactivé le runtime PM pour les fonctions GPU utilisées par le calcul. Les coûts d’énergie ont légèrement augmenté. Le débit a augmenté davantage.
Surtout, le cluster a cessé de mentir sur sa disponibilité.

La leçon : optimiser pour l’énergie sans plan de récupérabilité, c’est comme optimiser les performances de stockage en désactivant les checksums.
Vous aurez des chiffres. Vous n’aimerez pas la facture quand la réalité arrive.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une organisation de recherche exploitait un cluster GPU multi-tenant avec un mélange de générations matérielles. Ils avaient appris à la dure que
les problèmes de « reset GPU » ne sont pas répartis uniformément ; quelques nœuds sont toujours pires.

Leur pratique ennuyeuse : les nœuds étaient étiquetés avec une classe « fiabilité reset GPU » basée sur le comportement observé. Les jobs nécessitant
des redémarrages fréquents ou du provisioning éphémère étaient ordonnancés uniquement sur des nœuds « haute fiabilité ». Les jobs longue durée pouvaient s’exécuter n’importe où,
mais avec checkpointing et plan de préemption.

Ils avaient aussi un workflow de remédiation strict : un nœud qui loggait une défaillance de reset était immédiatement vidé, redémarré, et ne revenait en service
qu’après avoir passé une boucle de tests standardisés d’attach/detach. Pas de debugging héroïque pendant les heures de bureau.

Quand une nouvelle version de pilote a introduit plus de cas limites de reset sur une famille GPU, l’impact a été contenu.
L’ordonnanceur a évité les nœuds à risque, la boucle vider-redémarrer a empêché les longues tempêtes AER, et les utilisateurs voyaient majoritairement des jobs redémarrer
plutôt que de rester bloqués. Ce n’était pas glamour. C’était correct.

Erreurs courantes (symptômes → cause racine → correction)

1) Symptom: « reset failed » after detach; GPU won’t reattach

Cause racine : Le périphérique ne supporte pas un FLR fiable ; le chemin de reset du pilote est incomplet ; GPU bloqué dans l’état interne du firmware.
Correction : Évitez les detach/attach fréquents ; épinglez le GPU à la durée de vie de la VM ; n’utilisez bus reset qu’avec un port descendant isolé ; sinon redémarrez le nœud.

2) Symptom: GPU present in lspci but driver bind fails with timeouts

Cause racine : GPU en D3cold ou la plateforme ne le réveille pas ; conflit runtime PM.
Correction : Forcez /sys/bus/pci/devices/…/power/control sur on ; ajustez les réglages PCIe dans le BIOS ; assurez-vous que le périphérique est en D0 avant rebind.

3) Symptom: AER corrected errors increase; occasional job failures

Cause racine : Intégrité du signal/problèmes de lien, riser défectueux, lien dégradé, slot marginal.
Correction : Reseat le GPU, échangez le riser/câble, vérifiez la largeur/vitesse du lien, mettez à jour le firmware ; mettez le nœud en quarantaine si persistant.

4) Symptom: Unloading GPU driver hangs forever

Cause racine : Le pilote attend que les moteurs matériels s’inactivent ; microcontrôleur GPU bloqué.
Correction : Ne vous battez pas contre ça. Videz et redémarrez. Ensuite étudiez pourquoi les blocages arrivent (thermique, firmware, workload, overclock, alimentation).

5) Symptom: VFIO works once per boot only

Cause racine : Le reset fonctionne au cold boot mais pas après qu’un guest a utilisé le GPU ; un quirk vendeur manque ou nécessite un bus reset/cycle d’alimentation.
Correction : Validez la capacité de reset avant déploiement ; prévoyez un redémarrage hôte entre assignations ; préférez le matériel avec reset éprouvé.

6) Symptom: VM shutdown triggers host instability or other devices reset

Cause racine : Vous avez utilisé un bus reset sur un bridge partagé avec d’autres endpoints (stockage, NIC).
Correction : Cartographiez la topologie ; isolez les GPUs derrière des root ports dédiés ; ne faites pas de bus reset sur des segments partagés en production.

7) Symptom: « It worked in staging » but fails under churn

Cause racine : Les cycles de test n’ont pas couvert une longue exécution, une forte utilisation VRAM, ou des detach/attach répétés ; les états firmware dépendent du workload.
Correction : Ajoutez des tests de soak avec boucles detach/attach ; classez les nœuds selon la fiabilité de reset observée ; automatisez la remédiation.

Listes de contrôle / plan étape par étape

Checklist A: Before you deploy VFIO GPU passthrough at scale

  1. Vérifier IOMMU activé dans le BIOS et kernel ; confirmer les messages DMAR/AMD-Vi.
  2. Confirmer les fonctions GPU et s’assurer qu’elles sont toutes prises en compte (graphics/audio/USB).
  3. Cartographier les groupes IOMMU et la topologie ; identifier les ports en amont et les segments partagés.
  4. Exécuter un test de soak detach/attach (des dizaines à centaines de cycles) sous workload réel (pression VRAM + compute).
  5. Décider de votre contrat de récupération : « récupérer sans reboot » ou « reboot acceptable ». Mettez-le dans le runbook.
  6. Implémenter la mise en quarantaine du nœud : si un reset échoue une fois, retirez le nœud de l’ordonnancement jusqu’à remédiation.

Checklist B: Safe recovery ladder during an incident

  1. Arrêter ou migrer le workload ; s’assurer qu’aucun processus n’utilise le GPU.
  2. Capturer des preuves : tail de dmesg, lspci -vv état du lien, état d’alimentation, binding pilote courant.
  3. Tenter FLR via sysfs reset sur la fonction.
  4. Si toujours cassé, et seulement si la topologie est sûre : reset du port/bridge en amont.
  5. Si tempêtes AER ou échecs répétés : vider le nœud, redémarrer, marquer le nœud pour enquête approfondie.

Checklist C: Make it boring (the best kind of reliable)

  1. Étiquetez les nœuds par famille GPU/firmware et comportement de reset observé.
  2. Ordonnez les workloads à churn élevé seulement sur les nœuds « bon reset ».
  3. Désactivez le runtime PM pour les GPUs en passthrough sauf si vous avez la preuve que c’est sûr.
  4. Gardez versions kernel/driver/firmware contrôlées ; déployez les changements avec canaris et plans de rollback.
  5. Automatisez les boucles reboot + tests de santé ; traitez les reboots comme un outil de maintenance, pas une faute de caractère.

FAQ

Q1: If the GPU is in its own IOMMU group, why can’t it always be reset?

L’appartenance IOMMU concerne les frontières d’isolation DMA. La capacité de reset dépend du support des resets PCIe, des domaines d’alimentation, de l’état du firmware
et de la topologie. Ils sont liés mais pas équivalents.

Q2: Is this only an AMD problem?

Non. Les différents vendeurs montrent des patterns différents, mais les échecs de reset existent across GPU families. La communauté VFIO a historiquement
mis en lumière des cas AMD, mais NVIDIA et d’autres peuvent aussi se bloquer selon le modèle, le firmware et le chemin pilote.

Q3: Does SR-IOV or MIG eliminate reset issues?

Cela change le problème. Les fonctionnalités de partitionnement peuvent réduire le churn sur le périphérique entier, ce qui aide. Mais vous avez toujours les sémantiques de reset au
niveau de la physical function, et des bugs firmware/driver peuvent toujours apparaître sous de lourdes conditions multi-tenant.

Q4: Can I fix this purely in software with kernel parameters?

Parfois vous pouvez améliorer le comportement (surtout autour de la gestion d’alimentation ou du binding pilote), mais vous ne pouvez pas résoudre par logiciel un périphérique
qui nécessite un reset fondamental. Traitez la sélection matérielle et la topologie comme des éléments de première importance.

Q5: What’s the safest reset to try first?

Le reset par fonction (FLR) via sysfs est généralement le moins disruptif. S’il échoue, les étapes suivantes dépendent de la topologie. Les bus resets peuvent marcher mais
entraînent des risques collatéraux.

Q6: Why does the GPU sometimes work after a host reboot but not after VM detach/attach?

Le cold boot établit une baseline propre : le firmware s’initialise depuis zéro, les rails d’alimentation sont cyclés, le lien se réentraîne proprement. Un cycle detach/attach
repose souvent sur des resets partiels et des chemins de teardown du pilote, qui ne réinitialisent pas toujours l’état interne du GPU.

Q7: Should I disable AER to stop log spam?

En général non. AER rapporte les symptômes. Le désactiver masque les preuves pendant que le lien continue à mal fonctionner.
Si des tempêtes AER causent des problèmes opérationnels, mettez le nœud en quarantaine et corrigez le link/power/plateforme sous-jacent.

Q8: Is it acceptable to plan for reboots as the recovery method?

Oui, si vous concevez pour cela. Dans les clusters, « redémarrer pour récupérer un GPU bloqué » peut être parfaitement raisonnable si les jobs sont redémarrables,
les nœuds sont vidés en sécurité, et le chemin de redémarrage est rapide et automatisé.

Q9: Why does unbinding the driver sometimes hang?

Parce que le pilote tente un teardown sûr : il attend que le DMA s’arrête et que les moteurs se quiescent. Si le GPU est bloqué, le pilote
ne peut pas de bonne foi prétendre qu’il est libre. Ce blocage protège souvent contre la corruption mémoire.

Q10: What’s the single best metric to alert on?

Alertez sur les échecs de reset et les événements AER récurrents sur les root ports GPU. Ils corrèlent fortement avec « ce nœud va vous faire perdre du temps plus tard ».
Automatisez ensuite la mise en quarantaine et la remédiation.

Conclusion : prochaines étapes pratiques

Si vous ne retenez qu’une chose : IOMMU vous donne la sécurité DMA, pas la sécurité de reset. La classe de bugs « reset GPU » arrive quand on
confond ces deux notions et qu’on construit de l’automatisation qui suppose que les périphériques se comportent comme des périphériques sans état.

Prochaines étapes qui rapportent immédiatement :

  1. Inventairez la topologie : cartographiez ports en amont, bridges partagés et groupes IOMMU pour chaque nœud GPU.
  2. Implémentez une échelle de reset : FLR → bus reset prudent (seulement si isolé) → vider et redémarrer.
  3. Désactivez le runtime PM pour les GPUs en passthrough si vous observez des anomalies D3cold/D3hot.
  4. Adoptez la mise en quarantaine de nœud : un échec de reset doit retirer un nœud de l’ordonnancement jusqu’au reboot + test de santé.
  5. Changez les critères d’achat : exigez un comportement de reset prouvé, le contrôle d’alimentation du slot si possible, et des plateformes conçues pour la virtualisation.

C’est comme ça que vous transformez le « bug de réinitialisation GPU » d’un incident récurrent en une contrainte connue avec une réponse ennuyeuse et fiable.
L’ennuyeux, c’est bien. L’ennuyeux vous rend vos week-ends.

← Précédent
GPT vs MBR : se tromper casse le démarrage — suivez cette règle
Suivant →
OpenVPN : pourquoi il semble lent (et les réglages qui le font décoller)

Laisser un commentaire