Ce que fait l’ASPM
L’Active State Power Management (ASPM) PCIe permet aux liens PCIe d’entrer dans des états basse consommation quand ils sont au repos. La spécification PCIe définit plusieurs états de lien :
L0 est l’état pleinement actif. Le lien est établi, les deux extrémités sont alimentées, les données peuvent circuler immédiatement.
L0s est un état de repos léger. Le lien s’éteint partiellement. Le retour en L0 prend environ 1 à 4 µs selon le matériel. Chaque extrémité peut entrer en L0s indépendamment.
L1 est un état de repos plus profond. Les deux extrémités du lien s’éteignent ensemble. Le retour en L0 prend plus longtemps — typiquement 2 à 32 µs, parfois davantage. Le temps de reprise exact dépend de l’équipement, de la génération PCIe et de la plateforme.
L1.1 et L1.2 sont des sous-états de L1 introduits en PCIe 3.0. Ils réduisent encore la consommation en coupant la référence d’horloge de la PLL. Le retour depuis L1.2 peut prendre 32 à 100 µs. Pour un périphérique de stockage, ce n’est pas une erreur d’arrondi. C’est à peu près aussi long que la lecture que vous essayiez de faire au départ.
L’idée est simple. Si un lien PCIe est au repos pendant quelques microsecondes, on le fait passer dans un état moins gourmand. Quand le trafic reprend, on le réveille. On économise un peu d’énergie entretemps.
Sur un portable ou une machine de bureau qui passe le plus clair de son temps à ne rien faire, l’ASPM économise vraiment. Quelques watts par lien, cumulés sur tous les équipements PCIe du système. Sur un serveur qui fait tourner des charges intensives en E/S, les liens sont rarement au repos assez longtemps pour que l’ASPM serve à grand-chose.
Pourquoi ça pose problème sous passthrough
Sur du matériel nu, le système d’exploitation et le pilote de l’équipement négocient la gestion d’énergie ensemble. Le pilote NVMe sait quand le lien va passer au repos et quand il va soumettre de nouvelles E/S. Le sous-système PCIe du noyau coordonne les transitions d’état du lien avec le pilote. Tout est synchronisé.
Sous passthrough VFIO, cette coordination s’effondre.
Le noyau hôte contrôle toujours le lien PCIe physique. La VM invitée possède l’équipement via VFIO, mais elle ne contrôle pas le lien lui-même. Le sous-système PCIe de l’hôte voit le lien passer au repos — parce que du point de vue de l’hôte, aucun pilote côté hôte ne l’utilise. Il fait passer le lien dans un état basse consommation. Quand l’invité soumet une E/S, l’équipement a besoin que le lien revienne en L0. Le temps de reprise apparaît comme de la latence ajoutée sur cette opération d’E/S.
Le résultat, c’est une latence irrégulière.
La plupart des E/S se terminent à la vitesse normale.
Certaines prennent bien plus longtemps parce qu’elles tombent sur un lien en L1 ou L1.2 qui doit d’abord se réveiller.
Ça se voit comme un large étalement dans vos percentiles de clat (latence d’achèvement).
La moyenne peut avoir l’air très bien.
Le p99 peut être 5 à 10 fois plus haut.
C’est difficile à repérer parce que les chiffres de débit moyen peuvent sembler corrects. Vous ne voyez le problème qu’en regardant la latence de queue. Beaucoup de tests de performance ne la mettent pas en avant si vous ne demandez pas une sortie en percentiles.
La subtilité propre à VFIO
Il y a ici une subtilité qui va au-delà du simple problème de l’hôte et de l’invité se disputant l’état du lien.
Quand un équipement est rattaché à vfio-pci sur l’hôte, le noyau hôte sait qu’il est en mode passthrough.
Mais la politique ASPM PCIe s’applique au niveau du lien, pas au niveau de l’équipement.
La politique ASPM de l’hôte s’applique toujours au lien physique parce que l’hôte possède toujours la topologie PCIe.
VFIO n’intercepte ni ne surcharge les transitions ASPM. Il fait passer l’espace BAR et les interruptions de l’équipement, mais la gestion d’énergie du lien reste sous contrôle de l’hôte. L’invité n’a aucun moyen de dire à l’hôte « garde ce lien en L0 ».
Certains matériels et certaines versions de noyau récents s’en sortent mieux que d’autres. Ainsi, l’approche la plus sûre est de sortir complètement l’ASPM du tableau.
Comment le désactiver
Ajoutez pcie_aspm=off à la ligne de commande du noyau hôte :
# Edit /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet pcie_aspm=off"
# Update GRUB and reboot
update-grub
reboot
Ceci empêche l’hôte de placer un lien PCIe quelconque dans un état basse consommation. Ça s’applique globalement. À tous les équipements PCIe de l’hôte, pas seulement à celui qui est passé en passthrough.
Vérifiez après redémarrage :
# Should show "ASPM Disabled" for all devices
lspci -vv | grep -i "ASPM"
Le coût en énergie
Désactiver l’ASPM augmente bel et bien la consommation au repos. Chaque lien PCIe qui serait autrement en L1 reste en L0 et consomme quelques centaines de milliwatts de plus. Sur un système avec dix ou quinze équipements PCIe, ça peut faire 2 à 5 watts de plus au repos.
Pour un serveur en centre de données, 2 à 5 watts est une erreur d’arrondi sur la facture. Pour un homelab, c’est une fraction de ce que consomment le CPU et la mémoire. Pour un portable, ça compte. Mais vous ne feriez pas de passthrough VFIO sur la batterie d’un portable.
Le compromis est net. Quelques watts au repos contre des pics de latence imprévisibles sur vos équipements en passthrough. Sur tout système qui fait du passthrough, l’ASPM devrait être coupé.
Les états d’énergie au niveau de l’équipement
L’ASPM contrôle l’état d’énergie du lien PCIe. Les équipements ont aussi leur propre gestion d’énergie — les états D PCIe (de D0 à D3).
Quand un équipement est en D3 (complètement éteint), ce n’est pas seulement le lien qui dort. L’équipement lui-même s’est arrêté.
Sous passthrough VFIO, le pilote vfio-pci de l’hôte peut placer l’équipement en D3 quand la VM ne tourne pas ou quand la politique de gestion d’énergie de l’hôte estime qu’il est au repos.
Certains contrôleurs NVMe ne gèrent pas proprement la transition D3 vers D0. Ils ne reviennent pas correctement, l’invité perd l’équipement, et la seule issue est un redémarrage de la VM, parfois de l’hôte.
Le Samsung 990 EVO Plus est un fautif bien connu.
La correction est l’option de module disable_idle_d3 pour vfio-pci :
# /etc/modprobe.d/vfio.conf
options vfio-pci disable_idle_d3=1
Ceci empêche vfio-pci de placer en D3 un équipement rattaché quand il est au repos.
Comme pcie_aspm=off, c’est un réglage global. Tout équipement rattaché à vfio-pci reste en D0.
C’est en général ce que vous voulez pour du passthrough, où l’invité devrait être le seul à contrôler l’état d’énergie de l’équipement.
L’option disable_idle_d3 est distincte de l’ASPM.
L’ASPM contrôle le lien.
D3 contrôle l’équipement.
Les deux peuvent poser problème indépendamment.
Pour une configuration de passthrough propre, désactivez les deux.
Contrôle de l’ASPM équipement par équipement
Si vous ne voulez pas désactiver l’ASPM globalement — peut-être avez-vous d’autres équipements PCIe sur l’hôte qui profitent de l’économie d’énergie — vous pouvez contrôler l’ASPM lien par lien via sysfs :
# Find the link's ASPM policy
cat /sys/bus/pci/devices/0000:XX:00.0/link/l1_aspm
# Disable ASPM for a specific link
echo 0 > /sys/bus/pci/devices/0000:XX:00.0/link/l1_aspm
C’est plus ciblé mais moins fiable au fil des redémarrages et des mises à jour du noyau.
Pour la plupart des configurations de passthrough, le drapeau noyau global pcie_aspm=off est plus simple et plus prévisible.
Quand l’ASPM n’est pas le problème
Toute gigue de latence n’est pas de l’ASPM.
Si vos percentiles de clat sont hauts de façon constante (et pas seulement la queue), le problème vient plus probablement de la surcharge de traduction IOMMU, d’un mauvais alignement NUMA ou d’un MPS mal apparié.
L’ASPM produit un motif bimodal bien particulier — la plupart des E/S sont rapides, quelques-unes sont lentes — parce qu’il n’affecte que les E/S qui arrivent au moment où le lien est dans un état basse consommation.
Cherchez d’abord du côté de l’ASPM quand vous voyez :
- une latence p99 5 fois ou plus supérieure à la moyenne
- des résultats
fioincohérents d’une exécution à l’autre - une latence qui s’améliore sous charge soutenue mais se dégrade sur des charges en rafales
Si la latence est mauvaise de façon constante quel que soit le profil de charge, cherchez ailleurs. L’ASPM vaut la peine d’être écarté tôt parce que c’est bon marché à tester. Ce n’est pas pour autant la réponse à tout lien lent, et le poursuivre quand les chiffres ne collent pas au motif, c’est un après-midi que vous ne récupérerez pas.
Références
- Documentation PCI du noyau Linux — paramètres ASPM — le source du noyau qui couvre
pcie_aspm=offet les options associées - Forum Proxmox — passthrough PCI NVMe, impossible de changer l’état d’énergie — le fil communautaire qui couvre
disable_idle_d3pour les contrôleurs NVMe Samsung - Wiki Proxmox VE — passthrough PCI(e) — la documentation officielle sur la configuration du passthrough