Ubuntu 24.04 : NVMe disparaît sous charge — paramètres d’alimentation/ASPM qui le résolvent souvent

Cet article vous a aidé ?

Vous poussez de l’I/O — point de contrôle de base de données, fenêtre de sauvegarde, ferme de compilation, peu importe — et soudain le NVMe se met à… disparaître.
Un instant c’est /dev/nvme0n1, l’instant d’après c’est un mystère archéologique. Votre système de fichiers passe en lecture seule, votre RAID/ZFS hurle,
et votre supervision s’allume comme un sapin de Noël dont vous n’avez pas demandé le cadeau.

Sur Ubuntu 24.04, ce motif « le NVMe disparaît sous charge » n’est souvent pas un SSD mourant. C’est la gestion d’alimentation : ASPM côté PCIe sur le lien,
et/ou APST côté contrôleur NVMe. Les deux peuvent être parfaitement corrects en théorie et catastrophiques en pratique quand le firmware de la plateforme,
la topologie PCIe ou le firmware du disque deviennent créatifs. Voici la manière pragmatique et adaptée à la production pour diagnostiquer rapidement, corriger en sécurité et prouver que c’est résolu.

Ce que signifie réellement « le NVMe disparaît » (et pourquoi ce n’est rarement magique)

Quand les opérateurs disent « le NVMe a disparu », ils veulent généralement dire l’une des trois choses suivantes :

  1. Le périphérique bloc disparaît :
    /dev/nvme0n1 n’est plus présent, udev l’a retiré, et tout ce qui était monté dessus devient un mauvais jour.
  2. Le périphérique reste, mais l’I/O bloque :
    il est toujours listé, mais les lectures/écritures se bloquent, expirent, puis le noyau escalade en réinitialisation du contrôleur.
  3. La fonction PCIe devient non réactive :
    le contrôleur NVMe est présent sur le bus, mais le lien clignote ou AER (Advanced Error Reporting) crie à l’aide.

« Sous charge » est l’indice clé. La profondeur de file élevée, les écritures soutenues, le DMA massif et le stress thermique amplifient toutes les sensibilités temporelles.
C’est à ce moment que les transitions d’état d’alimentation qui « fonctionnent généralement » commencent à perdre des courses de temps.

Si cela se produit sur Ubuntu 24.04, vous êtes probablement sur un noyau moderne et une pile NVMe récente. C’est bon pour les fonctionnalités.
C’est aussi pratique pour découvrir que la gestion d’alimentation de votre plateforme a été conçue par un comité dont le travail s’est arrêté à « ça boote Windows ».

Faits & contexte historique qui expliquent le bazar

  • ASPM est antérieur à NVMe : PCIe Active State Power Management a été conçu pour économiser la puissance du lien bien avant que NVMe ne devienne le standard pour le stockage.
  • APST NVMe existe parce que la consommation à l’arrêt comptait : Autonomous Power State Transitions ont été créés pour laisser les contrôleurs économiser de l’énergie sans intervention constante de l’OS.
  • AER est devenu courant avec l’accélération de PCIe : des vitesses de lien plus élevées et des marges plus fines ont rendu le reporting d’erreurs et la récupération plus critiques — et plus visibles dans les logs.
  • Les firmwares NVMe grand public optimisent souvent pour les benchs : des performances en rafale excellentes peuvent masquer des cas limites sous des charges soutenues et mixtes.
  • Les ordinateurs portables ont poussé des valeurs par défaut agressives : de nombreux vendeurs privilégient l’autonomie, livrant parfois des firmwares « optimistes » quant à la stabilité du lien.
  • Linux s’est amélioré en runtime PM au fil du temps : mais « mieux » signifie aussi « plus actif », ce qui augmente les chances de heurter des bugs spécifiques aux plateformes.
  • PCIe Gen4/Gen5 rendent l’intégrité du signal moins indulgente : plus la vitesse est élevée, plus une carte marginale ou un retimer peut se manifester par des « pertes aléatoires de périphériques ».
  • NVMe a plusieurs couches de timeout : timeouts du contrôleur, timeouts blk-mq, timeouts de système de fichiers et retries de plus haut niveau peuvent masquer le point réel de défaillance.
  • Ubuntu 24.04 utilise systemd avec des outils d’alimentation agressifs disponibles : l’espace utilisateur peut influencer le runtime PM et la politique, ce qui aide parfois — jusqu’à ce que ça aggrave.

La conclusion opérationnelle : vous avez une pile d’alimentation en couches (firmware de la plateforme, politique de lien PCIe, politique du contrôleur NVMe, runtime PM Linux).
Si une couche ment, les autres y croient poliment — jusqu’à ce que votre SSD vous fantôme en plein checkpoint.

Feuille de diagnostic rapide (vérifiez 1–2–3)

Quand vous êtes en astreinte, vous n’avez pas de temps pour la danse interprétative. Faites ceci dans l’ordre.

1) Confirmer qu’il s’agit bien d’un problème de périphérique/lien, pas d’une illusion de système de fichiers

  • Recherchez des timeouts nvme et des réinitialisations de contrôleur dans le log du noyau.
  • Recherchez des erreurs PCIe AER depuis le port amont (pcieport).
  • Confirmez si le périphérique de namespace a disparu ou est simplement bloqué.

2) Identifier les fonctions d’alimentation en jeu

  • ASPM PCIe est-il activé sur le système ?
  • APST NVMe est-il activé (et quelles sont les latences d’inactivité) ?
  • Le runtime PM est-il en auto pour le périphérique PCI NVMe ?

3) Reproduire en sécurité et décider : stabiliser d’abord, optimiser ensuite

  • Exécutez une charge d’I/O contrôlée et observez les motifs d’erreur.
  • Appliquez le plus petit changement stabilisant (souvent désactiver ASPM et/ou APST).
  • Relancez la même charge et comparez les logs, pas les impressions.

Idée paraphrasée de Werner Vogels (fiabilité/ops) : « Tout échoue ; concevez pour que l’échec soit attendu et la récupération routinière. »

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

Voici les tâches que j’exécute réellement quand un NVMe se comporte mal sous charge. Chacune inclut (a) la commande, (b) ce que signifie une sortie typique,
et (c) la décision à en tirer.

Task 1: Trouver rapidement les erreurs noyau liées à NVMe

cr0x@server:~$ sudo journalctl -k -b | egrep -i 'nvme|pcie|aer|timeout|reset' | tail -n 60
Dec 29 09:11:22 server kernel: nvme nvme0: I/O 123 QID 6 timeout, aborting
Dec 29 09:11:22 server kernel: nvme nvme0: Abort status: 0x371
Dec 29 09:11:22 server kernel: nvme nvme0: controller is down; will reset: CSTS=0x1
Dec 29 09:11:23 server kernel: pcieport 0000:00:1c.0: AER: Corrected error received: 0000:02:00.0
Dec 29 09:11:23 server kernel: pcieport 0000:00:1c.0: AER: device recovery successful

Ce que ça signifie : Des timeouts I/O NVMe plus des réinitialisations de contrôleur indiquent souvent une instabilité du lien/alimentation ou des blocages firmware.
Des AER corrigés sur le port amont sont un fort indice que le lien PCIe glisse.

Décision : Si vous voyez timeouts/réinitialisations avec du bruit AER, priorisez les changements ASPM/politique du lien avant d’accuser le système de fichiers.

Task 2: Vérifier si le périphérique de namespace NVMe a réellement disparu

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,MODEL,SERIAL,MOUNTPOINTS | egrep -i 'nvme|NAME'
NAME        TYPE   SIZE MODEL               SERIAL            MOUNTPOINTS
nvme0n1     disk 931.5G ExampleNVMe 1TB     ABCD1234
├─nvme0n1p1 part   512M                                     /boot
└─nvme0n1p2 part   931G                                     /

Ce que ça signifie : Si nvme0n1 disparaît ici après l’incident, udev l’a retiré parce que le contrôleur a quitté le bus ou a subi une défaillance grave.
S’il reste présent mais que l’I/O bloque, le contrôleur peut être bloqué mais toujours énuméré.

Décision : « Disparu de lsblk » vous oriente vers des problèmes PCIe/lien/alimentation ou des réinitialisations complètes ; « présent mais bloqué » peut encore être lié à l’alimentation, au firmware ou au thermique.

Task 3: Inspecter l’état du contrôleur NVMe via nvme-cli

cr0x@server:~$ sudo nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1      ABCD1234             ExampleNVMe 1TB                           1         120.0  GB /  1.00  TB    512   B +  0 B   3B2QEXM7

Ce que ça signifie : Si nvme list échoue de manière intermittente ou n’affiche aucun périphérique au moment du problème, le contrôleur quitte le bus.

Décision : Si le contrôleur disparaît, concentrez-vous d’abord sur la gestion d’alimentation PCIe et le firmware de la plateforme ; SMART ne vous sauvera pas si le bus est parti.

Task 4: Récupérer SMART/health et rechercher médias vs transport

cr0x@server:~$ sudo nvme smart-log /dev/nvme0
Smart Log for NVME device:nvme0 namespace-id:ffffffff
critical_warning                    : 0x00
temperature                         : 54 C
available_spare                     : 100%
percentage_used                     : 2%
media_errors                        : 0
num_err_log_entries                 : 18
power_cycles                        : 23
power_on_hours                      : 410
unsafe_shutdowns                    : 6

Ce que ça signifie : Des erreurs média à zéro avec des entrées d’erreur qui augmentent pointent souvent loin d’une défaillance NAND et plutôt vers des réinitialisations du transport/contrôleur.
Les unsafe_shutdowns qui augmentent sont cohérents avec des événements « contrôleur disparu ».

Décision : Si les erreurs média sont faibles/à zéro mais que les réinitialisations/timeouts sont fréquents, ne demandez pas immédiatement un RMA ; stabilisez l’alimentation/le lien et retestez.

Task 5: Lire le journal d’erreurs NVMe pour confirmer les motifs timeout/reset

cr0x@server:~$ sudo nvme error-log /dev/nvme0 | head -n 20
Error Log Entries for device:nvme0 entries:64
Entry[ 0]
 error_count     : 18
 sqid            : 6
 cmdid           : 0x00a2
 status_field    : 0x4004
 parm_error_location: 0x0000
 lba             : 0
 nsid            : 1
 vs              : 0x00000000

Ce que ça signifie : Des erreurs répétées sur la même file sous charge peuvent s’aligner avec des réinitialisations du contrôleur et des aborts de commande. C’est généralement « le contrôleur s’est fâché », pas « les bits sont mauvais ».

Décision : Corrélez les sauts de error_count avec les réinitialisations noyau. S’ils coïncident, traitez-le comme un problème de stabilité/état d’alimentation.

Task 6: Identifier le chemin du périphérique PCIe (pour inspecter le port amont)

cr0x@server:~$ sudo lspci -nn | egrep -i 'non-volatile|nvme'
02:00.0 Non-Volatile memory controller [0108]: Example Corp NVMe Controller [1234:11aa] (rev 01)

Ce que ça signifie : Votre contrôleur NVMe est à 0000:02:00.0. Cette adresse devient votre ancre pour AER, ASPM, runtime PM et l’état du lien.

Décision : Utilisez ce BDF pour interroger lspci -vv, sysfs power control, et pour trouver le port amont qui pourrait générer des AER.

Task 7: Vérifier l’état du lien PCIe et l’état ASPM

cr0x@server:~$ sudo lspci -s 02:00.0 -vv | egrep -i 'LnkCap:|LnkSta:|ASPM|L1Sub|AER' -n
45:        LnkCap: Port #0, Speed 16GT/s, Width x4, ASPM L1, Exit Latency L1 <64us
52:        LnkSta: Speed 16GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
60:        L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+

Ce que ça signifie : Si LnkCap et les lignes associées montrent des modes ASPM supportés/activés, le lien peut entrer en états basse consommation.
Ce n’est pas incorrect en soi, mais c’est un suspect majeur quand les périphériques disparaissent sous charge ou lors de trafic en rafales.

Décision : Si vous avez des coupures et qu’ASPM est activé, tester avec ASPM désactivé vaut généralement le coup. Stabilisez d’abord.

Task 8: Confirmer si le noyau pense qu’ASPM est activé globalement

cr0x@server:~$ cat /sys/module/pcie_aspm/parameters/policy
default

Ce que ça signifie : Des politiques comme default, powersave ou performance influencent l’agressivité d’ASPM.
Certains systèmes sont stables en default ; d’autres prennent cela comme une suggestion de se défouler.

Décision : Si vous traquez des disparitions, prévoyez un démarrage test avec pcie_aspm=off. Si la stabilité revient, vous avez trouvé le coupable.

Task 9: Vérifier l’état APST NVMe (transitions autonomes du contrôleur)

cr0x@server:~$ cat /sys/module/nvme_core/parameters/default_ps_max_latency_us
0

Ce que ça signifie : Une valeur 0 signifie généralement « pas de limite », ce qui permet des états de puissance profonds si le contrôleur/firmware le souhaite.
Sur certains disques, des transitions d’inactivité profondes peuvent interagir mal avec les rafales et provoquer des réinitialisations.

Décision : Pour des tests de stabilité, définissez une latence maximale conservatrice (ou désactivez APST) via un paramètre noyau. Ne devinez pas ; testez.

Task 10: Inspecter l’état du runtime power management pour la fonction PCI NVMe

cr0x@server:~$ cat /sys/bus/pci/devices/0000:02:00.0/power/control
auto

Ce que ça signifie : auto permet au noyau de suspendre en runtime le périphérique quand il le juge inactif.
Sur des plateformes instables, le runtime PM peut être la dernière poussée qui déclenche des bizarreries de lien/contrôleur.

Décision : Si vous observez des réinitialisations, testez en forçant le runtime PM sur on (pas d’autosuspend) pour le périphérique NVMe.

Task 11: Vérifier les timeouts NVMe configurés par le noyau

cr0x@server:~$ cat /sys/module/nvme_core/parameters/io_timeout
30

Ce que ça signifie : C’est le timeout I/O en secondes. L’augmenter peut masquer des symptômes (vous « attendrez plus longtemps » avant une réinitialisation),
mais cela ne corrige pas la cause si le contrôleur se déconnecte.

Décision : Ne « corrigez » pas les disparitions en gonflant les timeouts à moins d’être sûr que le périphérique est juste lent à cause du GC. Les disparitions ne sont pas des problèmes de latence.

Task 12: Stress test I/O de manière reproductible sans détruire la production

cr0x@server:~$ sudo fio --name=nvme-load --filename=/dev/nvme0n1 --direct=1 --rw=randwrite --bs=4k --iodepth=64 --numjobs=4 --runtime=120 --time_based=1 --group_reporting
nvme-load: (groupid=0, jobs=4): err= 0: pid=9123: Mon Dec 29 09:15:01 2025
  write: IOPS=82.1k, BW=321MiB/s (337MB/s)(38.6GiB/123002msec)
    lat (usec): min=48, max=21234, avg=311.42, stdev=145.11

Ce que ça signifie : Vous voulez une charge reproductible qui déclenche le problème. Si le périphérique disparaît pendant ce test, vous avez un reproducer.
S’il ne disparaît que sous un pattern mixte read/write ou séquentiel, ajustez en conséquence.

Décision : Ne modifiez jamais les réglages d’alimentation à l’aveugle. Reproduisez, changez une variable, relancez, comparez les logs.

Task 13: Surveiller les événements AER en direct pendant le stress

cr0x@server:~$ sudo dmesg -wT | egrep -i 'aer|pcieport|nvme|timeout|reset'
[Mon Dec 29 09:16:22 2025] pcieport 0000:00:1c.0: AER: Corrected error received: 0000:02:00.0
[Mon Dec 29 09:16:22 2025] nvme nvme0: I/O 87 QID 3 timeout, aborting
[Mon Dec 29 09:16:23 2025] nvme nvme0: controller is down; will reset: CSTS=0x1

Ce que ça signifie : La séquence « AER corrected error » → « NVMe timeout » → « controller reset » est un scénario familier.

Décision : Considérez AER comme une preuve. Si la désactivation d’ASPM arrête le spam AER et les timeouts, vous avez très probablement résolu la cause racine.

Task 14: Vérifier les erreurs du port PCIe amont (pas seulement le endpoint NVMe)

cr0x@server:~$ sudo lspci -s 00:1c.0 -vv | egrep -i 'AER|UESta|CESta|Err' -n
78:        Capabilities: [100 v2] Advanced Error Reporting
96:        UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
104:       CESta:  RxErr+ BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-

Ce que ça signifie : Des erreurs corrigées comme RxErr+ indiquent des problèmes de signal ou des états d’alimentation marginaux.
Elles sont « corrigées » jusqu’à ce qu’elles ne le soient plus.

Décision : Si les erreurs corrigées augmentent pendant la charge, arrêtez de chasser l’optimisation du système de fichiers. Visez la gestion du lien et la stabilité de la plateforme.

Task 15: Vérifier que le disque ne throttle pas thermiquement au point d’instabilité

cr0x@server:~$ sudo nvme smart-log /dev/nvme0 | egrep -i 'temperature|warning|critical'
temperature                         : 73 C
critical_warning                    : 0x00

Ce que ça signifie : La température seule ne prouve pas la causalité, mais « disparaît sous charge » plus des températures élevées peut pousser des contrôleurs marginaux au-delà du seuil.

Décision : Si les températures sont élevées, améliorez le refroidissement et retestez avant de commencer à réécrire les paramètres de démarrage. La réalité matérielle l’emporte sur l’optimisme logiciel.

Pile d’alimentation : ASPM vs APST vs runtime PM (qui peut mettre votre disque hors ligne)

Il y a trois réglages que les gens confondent. Ne le faites pas. Ce sont des couches différentes, et vous pouvez les modifier indépendamment.

ASPM PCIe (économie d’énergie au niveau du lien)

ASPM contrôle les états basse consommation du lien PCIe (pas les états internes du contrôleur NVMe). Les protagonistes :
L0s et L1 (et des sous-états L1 comme L1.1/L1.2 sur les plateformes récentes).

Dans un monde parfait, l’endpoint et le root port négocient, entrent en états basse consommation quand inactifs, et sortent rapidement quand le trafic reprend.
Dans le monde réel, les promesses de latence de sortie sont parfois… aspirationales. Sous charge, vous pouvez obtenir des transitions à des moments inopportuns :
I/O en rafales, interruptions MSI/MSI-X, événements de power gating, et le bug firmware occasionnel qui dit « je suis réveillé » alors qu’il est très loin de l’être.

APST NVMe (états autonomes du contrôleur)

APST est interne au contrôleur NVMe. Il peut décider de se mettre dans des états plus profonds quand il est inactif, guidé par la politique OS (latence max)
et par les tables du disque. Si le firmware du disque est sensible, APST peut transformer « inactif puis occupé » en « inactif puis réinitialisation du contrôleur ».

APST est aussi l’endroit où les « correctifs » deviennent dangereusement populaires. Les gens le désactivent et le problème disparaît. Super.
Puis ils déploient cette configuration partout et se demandent pourquoi les portables perdent une heure d’autonomie. Les décisions en production ont des conséquences.

Runtime PM / autosuspend (économie d’énergie au niveau du périphérique par l’OS)

Le runtime PM est le noyau décidant « ce périphérique est inactif, suspendez-le ». Pour les périphériques PCI, cela peut signifier des D-states et des changements de lien.
C’est un multiplicateur : même si ASPM et APST vont bien, le runtime PM peut déclencher encore plus de transitions.

Une petite blague, promise et pertinente : la gestion d’alimentation PCIe, c’est comme une lumière à détecteur de mouvement dans un couloir — géniale jusqu’à ce que vous portiez quelque chose de fragile et qu’elle s’éteigne en plein pas.

Corrections qui fonctionnent généralement : paramètres noyau, udev et options BIOS

La stratégie gagnante est d’obtenir d’abord la stabilité avec le changement le moins invasif, puis de réintroduire les économies d’énergie prudemment.
Ne commencez pas par tout désactiver pour toujours à moins d’apprécier d’expliquer les augmentations de consommation au service financier.

Option de correction A : Désactiver ASPM PCIe (fort taux de succès pour « disparaît sous charge »)

C’est l’instrument brutal. Ça fonctionne souvent parce que ça retire entièrement le chemin de transition d’état du lien.
Cela peut augmenter un peu la consommation au repos, selon la plateforme.

Test temporaire (un démarrage)

Au menu GRUB, éditez la ligne de démarrage et ajoutez :
pcie_aspm=off

Changement persistant (GRUB)

cr0x@server:~$ sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="pcie_aspm=off /' /etc/default/grub
cr0x@server:~$ sudo update-grub
Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-xx-generic
Found initrd image: /boot/initrd.img-6.8.0-xx-generic
done

Ce que signifie la sortie : update-grub a regénéré la config de démarrage et trouvé votre kernel/initrd.

Décision : Redémarrez avec la nouvelle ligne de cmdline. Relancez votre reproducer (fio + dmesg en veille). Si les coupures cessent, gardez cela pendant que vous décidez d’un changement plus ciblé.

Option de correction B : Limiter ou désactiver APST NVMe (corrige souvent les « timeouts puis reset »)

Si le contrôleur entre dans des états NVMe profonds et n’arrive pas à revenir proprement, APST est le levier.
Sur Linux, le contrôle courant est nvme_core.default_ps_max_latency_us=.

Paramètres courants

  • Désactiver APST (souvent) : nvme_core.default_ps_max_latency_us=0 est parfois interprété comme « pas de limite » plutôt que « désactiver », selon le comportement du noyau et les tables du disque. En pratique, beaucoup d’opérateurs utilisent une petite valeur non nulle pour empêcher les états profonds.
  • Prévenir les états profonds : définissez une latence max basse, comme 1000 (1ms) ou 5000 (5ms), pour éviter les veilles les plus profondes tout en gardant quelques économies.

La vérité agaçante : le bon chiffre dépend de la plateforme et du disque. Ce n’est pas de la philosophie. Ce sont vos logs après tests contrôlés qui vous le diront.

Changement persistant (GRUB)

cr0x@server:~$ sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="nvme_core.default_ps_max_latency_us=5000 /' /etc/default/grub
cr0x@server:~$ sudo update-grub
Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.0-xx-generic
Found initrd image: /boot/initrd.img-6.8.0-xx-generic
done

Décision : Si ASPM-off corrige le problème, vous n’aurez peut-être pas besoin de tuner APST. Si les changements ASPM n’aident pas, APST est votre suspect suivant. Ne changez pas les deux en même temps sauf si vous cherchez seulement à arrêter l’hémorragie et que vous reviendrez isoler ensuite.

Option de correction C : Désactiver l’autosuspend runtime pour le périphérique PCI NVMe

Pour des systèmes où le runtime PM est trop malin, forcer la fonction PCI NVMe à rester « on » peut aider.
C’est une correction par périphérique, donc vous ne pénalisez pas toute la machine.

Immédiat (jusqu’au reboot)

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

Ce que ça signifie : Le périphérique est maintenant exclu de l’autosuspend runtime.

Décision : Si la stabilité s’améliore, rendez-le persistant avec une règle udev.

Persistant via règle udev

cr0x@server:~$ sudo tee /etc/udev/rules.d/80-nvme-runtimepm.rules >/dev/null <<'EOF'
ACTION=="add", SUBSYSTEM=="pci", KERNELS=="0000:02:00.0", ATTR{power/control}="on"
EOF
cr0x@server:~$ sudo udevadm control --reload-rules
cr0x@server:~$ sudo udevadm trigger -s pci

Ce que signifie la sortie : Aucune sortie est normale ; les règles udev ont été rechargées et ré-appliquées. Vérifiez par lecture sysfs.

cr0x@server:~$ cat /sys/bus/pci/devices/0000:02:00.0/power/control
on

Décision : Gardez ceci si cela résout le problème et que vous pouvez tolérer le compromis énergétique. C’est souvent moins agressif que de désactiver ASPM globalement.

Option de correction D : Réglages BIOS/UEFI (quand les leviers logiciels ne suffisent pas)

Si la cause racine est un comportement ASPM au niveau firmware ou un problème d’intégrité de signal sur la carte, le logiciel ne peut pas tout.
Bascules BIOS/UEFI utiles :

  • ASPM PCIe : désactiver ou mettre sur « off ». Certains vendeurs le cachent sous « Power » ou « Advanced > PCIe ».
  • Native ASPM : le désactiver peut forcer un comportement géré par le firmware ; l’activer peut laisser l’OS le contrôler. Ce qui aide dépend de la qualité du vendeur. Oui, cette phrase est agaçante.
  • Vitesse de lien PCIe : forcer Gen3 au lieu de Gen4 peut stabiliser des liens marginaux. C’est le coup « il faut que ça tienne aujourd’hui ».
  • C-states globaux / Package C-states : les états CPU profonds peuvent interagir avec le power gating du chipset. Désactiver les états les plus profonds est parfois une solution.

Si vous en arrivez à forcer Gen3 ou désactiver des C-states profonds pour garder le stockage en ligne, considérez-le comme un contournement d’un défaut matériel/firmware, pas comme « un tuning Linux ».

Option de correction E : Mises à jour firmware (NVMe + BIOS)

Les mises à jour firmware NVMe peuvent corriger les tables APST, la récupération après reset et des bugs d’état d’alimentation. Les mises à jour BIOS peuvent corriger le training PCIe et la politique ASPM.
Appliquez-les comme un adulte : gestion du changement, fenêtre de maintenance, options de rollback vérifiées quand possible.

Trois mini-histoires en entreprise (parce que la réalité est étrange)

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

Une équipe exploitait une petite flotte d’hôtes Ubuntu ingérant des logs dans une file locale sur NVMe. Les hôtes allaient bien pendant des semaines.
Puis une nouvelle version du pipeline a augmenté la concurrence d’écritures en rafale. Au début, ça ressemblait à du logiciel : corruption de file, retries étranges et pics de latence soudains.

L’hypothèse erronée était subtile : « Si SMART est propre, le disque va bien. » Leurs vérifications SMART ne montraient pas d’erreurs média et un spare correct.
Ils ont donc commencé à tuner l’application, élargir des tampons et ajouter des retries. Ça a réduit les erreurs visibles mais allongé le temps de récupération après un stall.

Lors d’une forte rafale, le noyau a loggué des timeouts I/O NVMe, puis une réinitialisation du contrôleur, puis le namespace a disparu. Le process manager a redémarré des services, sans effet.
Les hôtes sont revenus seulement après reboot. Le stockage « s’est réparé », ce qui est un très bon signe que ça va se reproduire.

Le mode de défaillance réel n’était pas l’usure NAND. C’était l’instabilité du lien PCIe sous une gestion d’alimentation agressive sur cette révision de carte mère.
Désactiver ASPM a immédiatement arrêté l’acte de disparition. L’équipe a ensuite testé la réactivation d’ASPM mais en limitant les latences APST NVMe. Ça a fonctionné sur certaines machines, pas toutes.

La leçon opérationnelle : SMART vous parle de la flash et de la santé du contrôleur, pas de la panique du lien PCIe.
Ils ont ajouté des motifs AER et réinitialisations NVMe à l’alerte, pour attraper la prochaine fois avant que le système de fichiers ne passe en lecture seule.

Mini-histoire 2 : L’optimisation qui a mal tourné

Une autre organisation a essayé de réduire la consommation dans un cluster de labo qui « pourrait devenir production ». Ils ont activé un profil d’énergie agressif et
réglé les politiques noyau pour économiser. Les machines étaient majoritairement inactives, avec des jobs de build lourds périodiques.

Sur le papier, c’était sensé : des machines au repos doivent économiser. En pratique, le cluster a commencé à perdre des périphériques NVMe pendant les rafales de build.
Le pattern était rageant : long idle, puis une tempête de compilation, puis une réinitialisation du contrôleur en plein write d’artéfact.

Ils ont chassé la perf pendant des semaines. Ce n’était pas le débit ; c’était un problème de transition d’état. La charge de build avait un comportement on/off tranché :
rien pendant des minutes, puis une activité extrême de métadonnées et d’écritures parallèles. C’est essentiellement un test de torture pour les états d’alimentation.

L’« optimisation » était runtime PM + ASPM profond + APST permissif. Ça faisait entrer la plateforme constamment dans des veilles profondes,
puis demander des réveils instantanés aux pires moments. Désactiver l’autosuspend runtime pour le NVMe a réparé la plupart des nœuds.
Les rares restants ont nécessité ASPM off.

La partie intéressante : une fois stable, ils ont réintroduit les économies d’énergie prudemment — un réglage à la fois, validé avec la même charge.
Les objectifs d’économie ont été en grande partie atteints sans sacrifier la fiabilité du stockage, mais seulement après qu’ils aient arrêté de traiter les réglages d’alimentation comme inoffensifs.

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

Un service lié à la finance tournait sur une paire de serveurs NVMe-intensifs. Rien de fancy. Juste une charge I/O stable et des exigences de disponibilité strictes.
Leur lead SRE était famosamente ennuyeux sur le contrôle des changements. Cette ennuyeuse prudence a payé.

Ils avaient l’habitude : chaque mise à jour de noyau/firmware avait un test préliminaire incluant un run de stress I/O et une checklist de revue de logs.
Ce n’était pas héroïque. C’était programmé, documenté et reproductible.

Après une mise à jour firmware plateforme, le stress test a commencé à produire des erreurs AER corrigées sur le port amont NVMe.
Pas encore d’incidents, pas d’impact applicatif visible, juste un nouveau bruit dans les logs. La plupart des équipes l’auraient ignoré parce que « corrigé ».

Ils n’ont pas déployé. Ils ont bisecté le changement : même OS, même noyau, seul le firmware avait changé. Les erreurs suivaient le firmware.
Ils ont rollbacké le firmware sur ce lot et ouvert un ticket fournisseur avec des preuves propres : logs avant/après, étapes de reproduction et sortie d’état du lien.

Des semaines plus tard, le fournisseur a fourni un firmware corrigé ajustant le comportement des états d’alimentation PCIe. Le service n’a jamais eu d’incident en production.
La pratique qui les a sauvé n’était pas du génie ; c’était refuser de déployer quand le système murmurait « je ne suis pas ok ».

Erreurs courantes : symptôme → cause profonde → correction

C’est là que la plupart des incidents passent de « ennuyeux » à « générateur de redémarrage ».

1) Symptom : « Le système de fichiers est passé en lecture seule, le NVMe doit mourir »

Cause profonde : réinitialisation du contrôleur ou chute du lien PCIe provoquant des erreurs I/O ; le système de fichiers s’est remonté en lecture seule pour se protéger.

Correction : confirmez avec journalctl -k pour timeouts/réinitialisations ; traitez ASPM/APST/runtime PM ; puis validez sous charge.

2) Symptom : « SMART est propre, donc le disque ne peut pas être en faute »

Cause profonde : l’instabilité du transport/lien n’apparaît pas forcément comme des erreurs média.

Correction : corrélez erreurs AER et réinitialisations NVMe ; vérifiez l’état du lien PCIe ; traitez comme un problème de plateforme.

3) Symptom : « Ça n’arrive que sous charge, donc c’est une surchauffe »

Cause profonde : ça peut être thermique, mais souvent c’est le timing des transitions d’état d’alimentation sous profondeur de file soutenue.

Correction : vérifiez les températures, oui ; mais reproduisez aussi avec ASPM off ou APST limité. Des solutions thermiques sans confirmation dans les logs ne sont que du cosplay HVAC.

4) Symptom : « Désactiver ASPM a corrigé, donc déployez partout »

Cause profonde : politique globale basée sur une combinaison plateforme/drive particulière.

Correction : traitez cela comme spécifique à un profil matériel. Sur les portables et déploiements sensibles à la batterie, essayez une correction plus étroite (limiter APST, désactiver autosuspend runtime pour NVMe uniquement).

5) Symptom : « J’ai augmenté nvme io_timeout et maintenant il ne réinitialise plus »

Cause profonde : vous avez transformé une défaillance nette en un blocage plus long. Le périphérique se bloque toujours ; vous attendez juste plus longtemps pour l’admettre.

Correction : revenez sur les tweaks de timeout ; corrigez l’instabilité sous-jacente ; n’utilisez les timeouts que pour ajuster le comportement de récupération une fois la stabilité prouvée.

6) Symptom : « Les erreurs AER corrigées sont sans gravité »

Cause profonde : les erreurs corrigées peuvent être des avertissements précoces d’un lien marginal qui deviendra non corrigible sous stress.

Correction : suivez les taux d’erreurs corrigées ; investiguez les pics ; testez en forçant la vitesse Gen ou en ajustant ASPM.

7) Symptom : « Ça n’arrive qu’après une période d’inactivité »

Cause profonde : états d’inactivité profonds (ASPM L1.2, APST PS profond, runtime suspend) plus une charge soudaine créent un chemin d’échec au réveil.

Correction : désactivez l’autosuspend runtime pour NVMe ; limitez la latence max APST ; envisagez ASPM off si nécessaire.

Deuxième et dernière blague : si votre NVMe disparaît sans cesse, félicitations — vous avez inventé le stockage cloud, sauf que le cloud est votre bus PCIe et il vous facture des intérêts.

Listes de contrôle / plan pas-à-pas

Pas-à-pas : stabiliser un NVMe instable sur Ubuntu 24.04 en production

  1. Capturer d’abord des preuves.
    Sauvegardez journalctl -k -b, lspci -vv pour le NVMe et le port amont, et nvme smart-log.
    Vous voulez des preuves avant/après.
  2. Déterminer la classe de défaillance.
    Dispositif disparu vs dispositif bloqué. « Disparu » pointe fortement vers PCIe/lien/alimentation ; « bloqué » peut être alimentation, firmware ou thermique.
  3. Reproduire avec une charge contrôlée.
    Utilisez fio sur le périphérique brut si c’est sûr, ou sur une partition test dédiée. Surveillez dmesg -wT en direct.
  4. Premier changement : désactiver ASPM pour un démarrage.
    Ajoutez pcie_aspm=off. Reproduisez. Si c’est corrigé, décidez si vous gardez ou testez une correction plus étroite.
  5. Deuxième changement : limiter APST NVMe.
    Ajoutez nvme_core.default_ps_max_latency_us=5000 (ou similaire) et testez. Ajustez selon les résultats.
  6. Troisième changement : désactiver l’autosuspend runtime pour la fonction PCI NVMe.
    Placez /sys/bus/pci/devices/.../power/control sur on ; persistez via udev si cela fonctionne.
  7. Valider les transitions idle→burst.
    La défaillance classique est « inactif pendant 10 minutes, puis pic ». Recréez ce pattern avec votre test.
  8. Vérifier le BIOS/UEFI si le logiciel ne suffit pas.
    Désactivez ASPM dans le firmware, forcez Gen3 ou ajustez les C-states temporairement pour confirmer la cause racine.
  9. Une fois stable, optimiser prudemment.
    Réactivez une fonctionnalité d’économie à la fois, mesurez et arrêtez-vous quand les erreurs reviennent.
  10. Opérationnaliser les garde-fous.
    Ajoutez des alertes pour réinitialisations/timeouts NVMe et pour les rafales AER PCIe. La stabilité sans détection n’est que surprise programmée.

Checklist de rollback (parce que vous en aurez besoin)

  1. Conservez l’accès console (IPMI/iDRAC/KVM) avant de modifier des paramètres noyau.
  2. Documentez la ligne précédente dans /etc/default/grub et conservez-en une copie.
  3. Appliquez un changement persistant à la fois ; redémarrez ; testez ; puis poursuivez.
  4. Si l’hôte ne démarre plus ou si le stockage change de comportement, retirez le dernier paramètre noyau et regénérez GRUB.

FAQ

1) Est-ce un bug d’Ubuntu 24.04 ?

Parfois c’est déclenché par des noyaux récents qui gèrent plus activement l’alimentation, mais la cause racine est souvent l’interaction plateforme/firmware/disque.
Ubuntu n’est que l’endroit où vous l’avez remarqué.

2) Dois-je désactiver PCIe ASPM ou NVMe APST en premier ?

Si le NVMe « disparaît » (quitte le bus) et que vous voyez du bruit AER/lien, désactivez ASPM d’abord.
Si c’est plutôt « timeouts puis reset » sans AER évident, essayez de limiter APST ensuite. En pratique, ASPM-off est le test binaire le plus rapide.

3) Désactiver ASPM va-t-il nuire aux performances ?

Généralement pas en termes de débit. Cela peut augmenter la consommation au repos et parfois affecter la micro-latence. Le vrai « coût » est l’efficacité énergétique,
qui compte davantage sur les portables et dans les fermes denses.

4) Désactiver APST va-t-il ruiner l’autonomie des portables ?

Ça peut. APST existe pour une raison. Préférez limiter la latence max APST plutôt que de supprimer toute gestion d’alimentation,
et n’appliquez des changements globaux qu’aux machines qui en ont besoin.

5) Je ne vois que des « AER corrected errors ». Dois-je m’en soucier ?

Oui, si elles coïncident avec des pics de charge ou précèdent des timeouts/réinitialisations NVMe. Les erreurs corrigées sont des avertissements précoces.
Si elles sont constantes et sans effet pendant des mois, peut-être ignorez ; si elles apparaissent soudainement après une mise à jour, investiguez.

6) Un mauvais câble peut-il causer des coupures NVMe ?

Pas pour les NVMe M.2 soudés sur la carte mère, mais pour U.2/U.3 ou des backplanes PCIe, absolument. Une mauvaise intégrité de signal ressemble à du bruit AER et des retrains de lien.
Dans les serveurs, « c’est le câble/backplane » est ennuyeux et fréquemment correct.

7) Dois-je forcer PCIe Gen3 comme contournement ?

Si vous avez besoin de stabilité immédiate et que votre lien est marginal en Gen4/Gen5, forcer Gen3 est une manœuvre de triage valide.
Vous renoncerez à la bande passante maximale, mais vous garderez le système de fichiers intact, ce qui est généralement un compromis acceptable.

8) Pourquoi ça arrive sous charge plutôt qu’à l’inactivité ?

La charge augmente la profondeur de file, l’activité DMA, les interruptions et la production thermique. Elle crée aussi des transitions rapides entre actif/inactif.
Ce sont ces transitions qui font trébucher la logique d’alimentation buggy.

9) Augmenter nvme_core.io_timeout est-ce jamais une bonne idée ?

Rarement, et seulement quand vous avez prouvé que le périphérique est lent mais stable (par exemple GC interne intensif) et que les réinitialisations nuisent plus que d’attendre.
Pour « le périphérique disparaît », les timeouts ne sont pas la solution.

10) Comment prouver que la correction a réellement fonctionné ?

Utilisez le même reproducer (pattern fio, durée, profondeur de file), comparez les logs noyau pour AER/timeouts/réinitialisations, et lancez un test idle→burst.
« On dirait que c’est mieux » n’est pas une stratégie de vérification.

Conclusion : prochaines étapes pratiques

Quand un NVMe disparaît sous charge sur Ubuntu 24.04, vous regardez généralement un cas limite de gestion d’alimentation :
ASPM PCIe sur le lien, APST NVMe dans le contrôleur, runtime PM dans l’OS, ou une combinaison charmante des trois.
La correction n’est presque jamais mystique. C’est de la discipline : capturez les logs, reproduisez, changez un seul réglage, et retestez.

Prochaines étapes qui rapportent rapidement :

  • Exécutez la feuille de route rapide : vérifiez les logs pour timeouts/réinitialisations NVMe et AER PCIe, confirmez si le périphérique a disparu ou est bloqué.
  • Testez un démarrage avec pcie_aspm=off. Si la stabilité revient, décidez de conserver ou d’essayer une correction plus ciblée.
  • Si nécessaire, limitez APST via nvme_core.default_ps_max_latency_us et/ou désactivez l’autosuspend runtime pour la fonction PCI NVMe.
  • Validez avec une charge reproductible et un test idle→burst, puis operationalisez des alertes pour les rafales AER et les réinitialisations NVMe.
← Précédent
MySQL vs MariaDB : le choix « par défaut » qui ralentit secrètement votre VPS
Suivant →
BlackBerry et le long adieu : comment les claviers ont cédé aux écrans tactiles

Laisser un commentaire