alliance-boreale/post-mortems/post-mortem-vishnu-freeze-am5.md
2026-05-14 08:54:41 -04:00

9.7 KiB

Post-mortem : freeze hard d'un nœud Proxmox AM5 — diagnostic et mitigation

TL;DR

Un nœud Proxmox/Ceph monté sur ASUS TUF X670E-Plus (Ryzen AM5) gelait sans trace, sans panic, sans rien dans les logs — reset manuel obligatoire. Cause : bug C-states profonds bien documenté sur AM5 sous Linux. Mitigation immédiate via processor.max_cstate=2 au cmdline kernel. Correction durable : flash BIOS vers une AGESA récente. Bonus : découverte d'une install Proxmox EFI avec grub-pc à la place de grub-efi-amd64 — silencieusement bancale depuis l'origine.

Contexte

  • Cluster : 3 nœuds Proxmox/Ceph (gandalf, asgard, vishnu)
  • Nœud problématique : vishnu — ASUS TUF Gaming X670E-Plus WiFi, BIOS 3602, AMD Raphael/Granite Ridge, kernel 6.8.12-20-pve
  • Particularité : seul nœud avec passthrough USB (stick FTDI 0403:6015 vers VM Home Assistant)
  • Storage local : 1 OSD HDD 9.1 TiB (LUKS), 1 OSD NVMe 1.8 TiB, NVMe 100 GiB pour DB
  • Symptôme : freeze hard récurrent, écran figé, plus aucune réponse réseau ni console, reset hardware obligatoire

Symptômes — ce qui rend le cas difficile

Le tableau clinique éliminait d'emblée plusieurs pistes classiques :

  • Aucun kernel panic à l'écran ou en pstore → pas de panic propre
  • Aucun message dans journalctl -k -b -1 | tail -100 avant la coupure → kernel n'a pas eu le temps d'écrire
  • Le softdog watchdog présent (soft_margin=60) n'a jamais déclenché de reboot automatique → pas un soft lockup détectable
  • Pas de redémarrage seul, intervention manuelle obligatoire
  • HEALTH_WARN Ceph avec slow ops BlueStore — mais sur osd.4 et osd.5 (situés sur les autres nœuds), pas sur osd.3 (vishnu). Donc Ceph subissait le freeze, n'en était pas la cause.

Bref : machine qui meurt instantanément, sans signal préalable. C'est le profil typique d'un blocage hardware ou d'un deadlock kernel total où plus aucune IRQ ne remonte.

Hypothèses écartées en cours de diag

Hypothèse Pourquoi écartée
Disque OSD mourant (slow ops BlueStore) Slow ops sur OSD distants, pas sur celui de vishnu — symptôme, pas cause
Quorum corosync perdu Logs corosync sains, quorum stable, MTU PMTUD négocié à 1397
OOM / pression mémoire Aucun message OOM dans les logs
MCE matérielle Aucune entrée MCE décodée par le kernel
Bug VFIO / IOMMU groups sales Vérifié — pas de PCI passthrough actif (uniquement USB par vendor:product)

L'indice qui a tout débloqué

Trois faits convergents :

  1. Hardware AM5 récent (Ryzen 7000/9000 sur X670E)
  2. Cmdline kernel nu : BOOT_IMAGE=/boot/vmlinuz-6.8.12-20-pve root=/dev/mapper/pve-root ro quiet — aucune mitigation, aucun paramètre IOMMU, aucun ajustement idle
  3. Profil de freeze : hard hang sans trace, propre à un seul nœud

Cette combinaison correspond à un bug largement documenté de l'écosystème AM5 sous Linux : sous certaines conditions de charge, le CPU descend dans un état d'idle profond (C3/C6) duquel il ne se réveille pas correctement à l'arrivée d'une IRQ. Le core est physiquement gelé — pas de fenêtre pour écrire un panic, pour qu'un watchdog software se déclenche, ou pour que la console réagisse.

C'est exactement ce que vishnu manifestait.

La mitigation appliquée

1. Modification du cmdline kernel

# Backup
cp /etc/default/grub /etc/default/grub.bak.$(date +%Y%m%d)

# Édition
sed -i 's|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt processor.max_cstate=2"|' /etc/default/grub

Trois paramètres :

  • processor.max_cstate=2 — la mitigation principale, bloque l'accès aux C-states ≥ C3
  • amd_iommu=on iommu=pt — passage du mode DMA "Translated lazy" (défaut) au mode passthrough optimisé, recommandé dès qu'il y a virtualisation

2. Filets de sécurité pour les prochaines fois

cat > /etc/sysctl.d/99-debug-freeze.conf <<EOF
kernel.sysrq = 1
kernel.nmi_watchdog = 1
kernel.softlockup_panic = 0
kernel.hung_task_timeout_secs = 60
EOF

Si le bug se reproduisait malgré la mitigation, le NMI watchdog hardware aurait une chance de réveiller un autre core et d'écrire une trace.

3. Découverte collatérale — install Proxmox EFI bancale

À l'update-grub, message inattendu :

System booted in EFI-mode but 'grub-efi-amd64' meta-package not installed!

Le serveur bootait en EFI mais avec le paquet grub-pc (BIOS legacy). L'EFI utilisait le binaire fallback \EFI\BOOT\BOOTX64.EFI au lieu d'une entrée \EFI\proxmox\ propre. Fonctionnel, mais aucune mise à jour de bootloader ne pouvait remonter.

Correction :

apt install grub-efi-amd64
# Remplace automatiquement grub-pc, déploie un GRUB EFI propre,
# crée l'entrée NVRAM Boot0000 'proxmox', relance update-grub

Vérification post-install :

efibootmgr -v
# Boot0000* proxmox  HD(...)/File(\EFI\proxmox\grubx64.efi)   ← nouvelle, en première position
# Boot0001* UEFI OS  HD(...)/File(\EFI\BOOT\BOOTX64.EFI)      ← l'ancienne, garde en fallback

4. Précaution Ceph avant reboot

Vu qu'un rebalance était en cours (4 PG remappés, 0.86% misplaced) :

ceph osd set noout    # avant reboot
# ... reboot ...
ceph osd unset noout  # au retour

Sans noout, Ceph aurait considéré que les OSD locaux de vishnu étaient durablement perdus et déclenché un rebalance plus agressif pendant les ~2 min de coupure.

Validation

Au retour du reboot :

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-20-pve root=/dev/mapper/pve-root ro quiet \
  amd_iommu=on iommu=pt processor.max_cstate=2

$ cpupower idle-info
CPUidle driver: acpi_idle
Available idle states: POLL C1 C2

Confirmation visuelle : les C-states ≥ C3 ne sont plus exposés par le driver. Le CPU continue à profiter de C2 (470 s cumulées d'idle dans les premières minutes), donc on n'a pas tué la gestion d'énergie — juste coupé l'accès aux états problématiques.

Plan correctif définitif

La mitigation kernel masque le symptôme. La cause racine est dans le firmware AGESA. Plan en deux temps :

  1. Court terme (validation 72 h) : laisser tourner sous charge normale avec processor.max_cstate=2 et observer. Pas de freeze pendant 72 h = mitigation confirmée efficace.

  2. Moyen terme (fenêtre planifiée) : flash BIOS vers la dernière version disponible (3842 au moment de l'incident, AGESA ComboAM5 PI 1.3.0.0a, qui mentionne explicitement des marges de stabilité supplémentaires pour configs Ryzen 9000). Procédure via USB BIOS Flashback — se fait à froid, sans CPU stable, en 5 min.

Si après le flash BIOS la mitigation kernel n'est plus nécessaire, on pourra retirer processor.max_cstate=2 (mais conserver amd_iommu=on iommu=pt, qui restent recommandés en virtualisation).

Si la mitigation ne suffit pas

Plan de repli progressif :

  1. processor.max_cstate=2 ne tient pas → descendre à processor.max_cstate=1
  2. Toujours pas → ajouter idle=nomwait (force la boucle d'idle à utiliser HLT au lieu de MWAIT)
  3. Toujours pas → désactiver Global C-states control dans le BIOS lui-même
  4. Si rien ne fonctionne, suspecter alimentation, VRM, ou barrette RAM marginale

Leçons

Le cmdline Proxmox par défaut est minimaliste. Sur AM5, ça suffit pour un boot fonctionnel mais pas pour de la stabilité long-terme sous charge virtualisée. Trois paramètres devraient être systématiques sur ce hardware : amd_iommu=on iommu=pt processor.max_cstate=2 (au moins jusqu'à BIOS récent confirmé sain).

Le hardware grand public a sa place dans un homelab — avec discipline. Une carte mère gaming AM5 fait un excellent nœud Proxmox, à condition de tenir le BIOS à jour et de connaître les ajustements kernel typiques de la plateforme. Ne pas le faire = freezes aléatoires que beaucoup imputent à tort à Linux ou à Proxmox.

Vérifier le boot loader d'une install Proxmox même quand "tout marche". Une install EFI avec grub-pc à la place de grub-efi-amd64 est silencieuse jusqu'au jour où une mise à jour critique ne s'applique pas. À auditer sur tout cluster avec : [ -d /sys/firmware/efi ] && dpkg -l | grep -E "grub-(pc|efi)".

Quand un nœud freeze sec sans trace, lister ce qui le différencie des autres est plus efficace que d'éplucher les logs (qui ne contiennent rien par définition). Ici c'était le hardware AM5 + le passthrough USB. Le second n'était pas la cause, mais la question "qu'est-ce que ce nœud fait que les autres ne font pas" a permis de cibler.

Commandes de référence — diagnostic freeze hard sans trace

# Hardware identification
dmidecode -s baseboard-product-name
dmidecode -s bios-version
dmidecode -s bios-release-date

# IOMMU groups (utile si VFIO suspecté)
for d in /sys/kernel/iommu_groups/*/devices/*; do
  n=${d#*/iommu_groups/*}; n=${n%%/*}
  printf 'IOMMU Group %s: ' "$n"; lspci -nns "${d##*/}"
done | sort -V

# Cmdline kernel actuel
cat /proc/cmdline

# C-states disponibles
cpupower idle-info

# Mode boot (EFI ou BIOS)
[ -d /sys/firmware/efi ] && echo "EFI mode" || echo "BIOS mode"

# Config bootloader Proxmox (LVM vs ZFS)
proxmox-boot-tool status 2>/dev/null
ls -la /boot/efi/EFI/

# Boot du dernier crash
journalctl -k -b -1 | tail -100
journalctl -b -1 -p err

Références utiles


Post-mortem rédigé suite à un diagnostic du 29 avril 2026. Hardware : ASUS TUF Gaming X670E-Plus WiFi, BIOS 3602. Stack : Proxmox VE 8 / kernel 6.8.12-20-pve / Ceph Quincy.