Certains jours votre NIC « virtualisé » consomme 2 % de CPU et transmet 25 Gbps sans broncher. D’autres jours il perd des paquets sous charge, votre latence p99 ressemble à un sismographe, et quelqu’un suggère « activez SR-IOV » comme si c’était une panacée.
Voici la version adulte de cette conversation : ce que SR-IOV et le passthrough vous apportent réellement, ce que fait vraiment l’IOMMU, et les façons précises de détériorer les performances en se félicitant d’« aller plus près du matériel ».
Le modèle mental : PF, VFs, DMA, et pourquoi l’IOMMU existe
Définissons les termes comme votre noyau les comprend, pas comme les slides commerciales.
Passthrough (VFIO) en un paragraphe
Le passthrough PCI assigne une fonction PCIe entière à une VM (ou une charge de type conteneur) de sorte que le guest possède l’appareil. Sous Linux/KVM c’est typiquement VFIO : l’hôte attache le périphérique à vfio-pci, et QEMU le mappe dans le guest. Le périphérique effectue des DMA vers la mémoire du guest, et l’IOMMU (si activé) garantit que les DMA restent dans ce que le guest est autorisé à toucher.
SR-IOV en un paragraphe
SR-IOV divise une fonction PCIe physique (PF) en plusieurs fonctions légères (VFs). Chaque VF ressemble à un périphérique PCI distinct avec son propre espace de configuration, ses BARs et ses files (selon l’implémentation), vous permettant d’attribuer des VFs individuelles aux guests. La PF reste gérée par l’hôte (ou parfois par une « service VM »), et la VF est « majoritairement matérielle », avec des réglages de politique exposés via le pilote PF et le firmware.
Où s’insère le DMA, et pourquoi cela vous concerne
SR-IOV et le passthrough traitent d’une seule chose : qui est autorisé à effectuer des DMA, et combien il en coûte pour le faire en toute sécurité. Les périphériques n’« envoient pas de paquets » ; ils effectuent des DMA de descripteurs et de charges utiles vers/depuis la mémoire. Si un périphérique peut faire des DMA n’importe où, il peut lire vos secrets, corrompre votre noyau et transformer la fiabilité en danse interprétative.
C’est le rôle de l’IOMMU : traduire et contraindre les adresses DMA des périphériques, de la même manière que le MMU du CPU contraint la mémoire des processus. Sans IOMMU, les périphériques « assignés » peuvent encore DMA dans la mémoire hôte si vous vous plantez sur l’isolation. Avec l’IOMMU, vous payez un coût de traduction (parfois minime, parfois non), mais vous obtenez une vraie contention et des fonctionnalités comme le remappage d’interruptions.
Règle pratique : si vous faites du passthrough en production et que vous n’utilisez pas d’IOMMU, vous n’êtes pas « courageux », vous avez juste un modèle de menace différent de celui que vous croyez avoir.
Blague n°1 : L’IOMMU est comme le videur d’une boîte de nuit pour les DMA. Il n’empêche pas les mauvaises décisions à l’intérieur, mais il tient les inconnus à l’écart.
Ce que « performance » signifie réellement ici
On entend souvent « SR-IOV est plus rapide que virtio ». Parfois. Mais il faut préciser quel axe de performance :
- Débit (Gbps ou IOPS) pour un budget CPU donné
- Latence de queue (p99/p999), surtout sous contention
- Jitter (variance), qui casse les applications pseudo-temps réel
- Efficacité CPU (cycles par paquet/IO)
- Performance opérationnelle (vitesse de diagnostic et de restauration de service)
SR-IOV et le passthrough peuvent être fantastiques pour le débit et l’efficacité CPU. Ils peuvent aussi aggraver la latence de queue si vous gérez mal les interruptions, ne pinnez rien et laissez l’ordonnanceur hôte improviser.
SR-IOV vs passthrough : les vrais compromis
Voici la version opinionnée :
- Si vous avez besoin qu’une VM possède un périphérique de bout en bout (GPU, FPGA, HBA) : utilisez le passthrough. SR-IOV n’est pas toujours disponible, et même quand il l’est, la parité de fonctionnalités est étrange.
- Si vous avez besoin que plusieurs guests atteignent des performances NIC proches du bare-metal : utilisez SR-IOV, mais considérez la gestion des VFs comme une composante de votre plateforme, pas comme un hobby par VM.
- Si vous avez besoin de flexibilité (migration à chaud, snapshots, hôtes hétérogènes) : préférez virtio et acceptez le coût CPU, sauf si vous avez une raison prouvée de ne pas le faire.
Sécurité et isolation : ce n’est pas la même histoire
Avec le passthrough, le guest obtient l’appareil entier. C’est excellent pour les performances et l’accès aux fonctionnalités, et terrible pour le partage. L’isolation dépend fortement de la correction de l’IOMMU et du comportement du périphérique. Avec SR-IOV, vous partagez un périphérique physique entre locataires, et l’isolation dépend de l’implémentation des VFs par le NIC (séparation des files, limitation de débit, vérifications anti-spoof) ainsi que du pilote PF. Certaines VFs peuvent faire des choses qu’elles ne devraient pas si vous laissez des drapeaux de confiance activés.
Conseils pratiques :
- SR-IOV multi-tenant est faisable, mais vous devez configurer explicitement la vérification anti-spoof des VF, l’application des VLANs et les réglages de trust sur la PF.
- Passthrough pour des guests non fiables est fortement couplé à l’IOMMU et au remappage d’interruptions. Si l’un ou l’autre manque, vous acceptez un risque.
Opérations : SR-IOV gagne jusqu’à ce que ça n’aille plus
SR-IOV semble opérationnellement « simple » parce que vous pouvez distribuer des VFs comme des bonbons. Puis vous rencontrez la complexité cachée :
- Provisioning des VFs et collecte des ordures après reboot
- Incompatibilités firmware/driver qui ne se manifestent qu’avec certains comptes de files
- Lacunes d’observabilité (les outils hôtes voient les stats PF ; le guest voit les stats VF ; personne ne voit « bout à bout »)
- Steering des paquets et affinité IRQ devenant une exigence plateforme
Le passthrough est plus simple dans le sens où un guest possède l’appareil et vous debuggez une seule pile. Il est plus difficile dans le sens où vous perdez beaucoup de commodités de virtualisation (migration, snapshots, oversubscription) et vous pouvez briquer le réseau d’un hôte si vous passez la mauvaise chose.
Le secret embarrassant : les deux approches exigent quand même l’hygiène Linux ennuyeuse
Pinning CPU, alignement NUMA, affinité IRQ, dimensionnement des rings et décisions MTU sensées comptent toujours. SR-IOV ne vous sauve pas d’une VM exécutée sur le mauvais socket, et le passthrough ne vous sauve pas d’un driver invité configuré comme une expérience scientifique.
Quand l’IOMMU aide (et pourquoi)
1) Contention : l’isolation DMA est l’objectif principal
Sans IOMMU, un périphérique effectuant des DMA peut accéder à des adresses physiques dont vous n’avez pas prévu l’accès. En passthrough, cela peut signifier qu’un périphérique contrôlé par le guest (ou la programmation du périphérique depuis le guest) peut lire ou corrompre la mémoire hôte. Avec l’IOMMU, l’espace d’adresses DMA (IOVA) est traduit via des tables contrôlées par l’hôte.
Avec SR-IOV, les VFs effectuent aussi des DMA. Si vous assignez des VFs à des guests, vous voulez quand même l’IOMMU activé pour confiner les DMA des VFs à la mémoire du guest. Oui, le NIC est « virtualisé », mais il reste un périphérique effectuant des DMA.
2) Remappage d’interruptions : moins de façons de se planter
Les IOMMUs modernes peuvent aussi remapper les interruptions (MSI/MSI-X) pour empêcher un périphérique d’injecter des interruptions de manière erratique. Cela compte lorsque vous passez des périphériques aux guests. Sans remappage d’interruptions, vous pouvez être forcé dans des modes non sûrs, ou obtenir un comportement instable selon le support plateforme.
3) Vous pouvez activer des fonctionnalités sûres qui seraient autrement risquées
Si vous faites de l’assignation de périphériques à grande échelle, l’IOMMU est la couche qui permet de dire « ce périphérique touche seulement ce qu’il est censé toucher ». Il permet de faire du passthrough pour de vrais workloads, pas seulement des setups de labo.
4) Certains chemins de performance supposent sa présence
Contre-intuitif : parfois laisser l’IOMMU désactivé déclenche des repliements du noyau, désactive le remappage d’interruptions, ou force différentes stratégies de mapping DMA. Sur certaines plateformes, « IOMMU off » n’est pas « mode rapide », c’est « mode compatibilité ». Vous ne choisissez pas votre aventure ; votre carte mère l’a déjà choisie.
Quand l’IOMMU n’aide pas (et peut nuire)
Maintenant la partie que les gens n’aiment pas entendre : l’IOMMU n’est pas un interrupteur magique de performance. C’est une fonctionnalité de sécurité avec des implications sur les performances. Parfois ces implications sont négligeables. Parfois elles se manifestent dans votre p99.
1) Le réseau à haute fréquence de petits paquets peut amplifier le surcoût de traduction
Si votre workload consiste en paquets de 64 octets à très haut PPS, le coût de mapping/unmapping DMA, la pression sur la TLB de l’IOMMU et les misses IOTLB peuvent apparaître. Les bons pilotes amortissent les coûts de mapping (mappings longue durée, hugepages, batching). Les mauvais setups churnent les mappings et en payent le prix.
2) Hugepages mal configurées ou fragmentation mémoire empirent le problème
Si la mémoire du guest est fragmentée, l’IOMMU nécessite plus d’entrées de tables de pages, ce qui augmente la probabilité de misses IOTLB. Avec des hugepages (et un bon pinning), vous réduisez l’empreinte de traduction. C’est pourquoi « SR-IOV est plus lent que virtio » apparaît parfois : ce n’est pas SR-IOV ; c’est la stratégie de mapping et la disposition mémoire.
3) Vous pouvez perdre des fonctionnalités que vous croyiez disponibles
Certaines configurations activent l’IOMMU dans un mode qui casse ou désactive le DMA peer-to-peer (device-to-device), ou change le comportement d’ATS/PRI (quand présent). Pour les piles de stockage qui dépendent de certains patterns DMA, vous pouvez constater des régressions qui ressemblent à un « bug de driver » mais qui sont en réalité des changements de comportement de traduction.
4) Le débogage devient plus difficile car les modes de défaillance se multiplient
Quand l’IOMMU est impliqué, une défaillance peut être :
- bug du driver invité
- bug VFIO/QEMU sur l’hôte
- bug/quirk de l’IOMMU plateforme
- mismatch de paramètre BIOS
- bizarreries d’ACS grouping
- comportement du firmware sous charge
Blague n°2 : Activer l’IOMMU pour « réparer les performances » c’est comme acheter une clé dynamométrique pour réparer un pneu crevé. Outil utile, mauvais problème.
Faits intéressants et contexte historique
- Les IOMMUs précèdent le battage cloud. Ils sont apparus sous diverses formes pour résoudre les limites d’adressage DMA et l’isolation bien avant que le « multi-tenant » ne devienne un argument produit.
- L’adressage DMA était autrefois une vraie contrainte. Les premiers systèmes avaient des périphériques qui ne pouvaient DMA que dans des plages d’adresses limitées ; les IOMMUs remappaient les adresses visibles par le périphérique.
- Intel VT-d et AMD-Vi ont rendu l’assignation de périphériques mainstream. Le remappage matériel des DMA est devenu une fonctionnalité standard pour les serveurs voulant une virtualisation sérieuse.
- MSI-X a changé la donne pour les NICs haute performance. Les multiples vecteurs d’interruption ont permis des designs file-par-core, sur lesquels SR-IOV s’appuie fortement.
- SR-IOV est une norme PCI-SIG. Ce n’est pas de la magie vendor ; les implémentations varient fortement en qualité et en options.
- Les « groupes IOMMU » parlent des limites d’isolation. Le grouping reflète ce que le matériel peut isoler ; ce n’est pas une invention Linux, c’est Linux qui expose la réalité.
- ACS est devenu le héros maladroit. Access Control Services influencent comment les périphériques sont isolés derrière des switches PCIe ; l’absence d’ACS peut forcer de larges groupes IOMMU.
- Virtio a mûri parce que les opérations l’ont exigé. Virtio n’est pas juste une « émulation plus lente ». Il a évolué en une interface paravirtuelle robuste et débogable adaptée aux opérations cloud.
- DPDK et le réseau en espace utilisateur ont élevé les attentes. Une fois que les gens ont vu le line rate en user space, ils ont exigé un comportement similaire dans les VMs, ce qui a poussé l’adoption de SR-IOV.
Méthode de diagnostic rapide
L’objectif est de trouver le goulot d’étranglement rapidement, pas de « tout comprendre du PCIe ». Vous pourrez faire cela plus tard.
Première étape : confirmez ce que vous avez réellement déployé
- Le workload utilise-t-il virtio, une VF SR-IOV, ou un périphérique en passthrough complet ?
- L’IOMMU est-elle activée et fonctionnelle (pas seulement « réglée dans le BIOS ») ?
- Les interruptions sont-elles remappées et MSI-X activé ?
Deuxième étape : localisez le domaine de contention
- Alignement NUMA : la VM est-elle sur le même socket que le périphérique PCIe ?
- Affinité IRQ : les interruptions sont-elles épinglées aux bons CPUs ?
- Nombre de files : avez-vous assez de files, ou trop ?
Troisième étape : décidez si vous êtes lié par le CPU, les IRQ, ou DMA/IOMMU
- Si le CPU est saturé en softirq/ksoftirqd : c’est le traitement des paquets et l’interruption/steering.
- Si le CPU est correct mais que le p99 est mauvais : regardez la migration des IRQ, les états de puissance, et le churn IOTLB.
- Si le débit est plafonné de façon suspecte : vérifiez la vitesse/largeur du lien, le PCIe négocié, et les offloads.
Quatrième étape : prouvez-le avec une expérience ciblée
- Pinnez les vCPUs et la mémoire sur le nœud NUMA du périphérique, retestez.
- Changez l’affinité IRQ pour les files VF, retestez.
- Basculez hugepages on/off (ou 2M vs 1G) sur un hôte, retestez.
Ne changez pas cinq variables et proclamez la victoire. C’est ainsi qu’on crée du folklore.
Tâches pratiques : commandes, sorties et décisions
Voici les contrôles que j’exécute réellement quand quelqu’un dit « SR-IOV est lent » ou « le passthrough est instable ». Chaque tâche inclut la décision que vous prenez à partir de la sortie.
Tâche 1 : Confirmer que l’IOMMU est activée dans le noyau
cr0x@server:~$ dmesg | egrep -i 'iommu|vt-d|amd-vi|dmari' | head -n 25
[ 0.142311] DMAR: IOMMU enabled
[ 0.142355] DMAR: Host address width 46
[ 0.142360] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[ 0.381200] DMAR-IR: Enabled IRQ remapping in x2apic mode
Ce que cela signifie : Vous avez le remappage DMA (DMAR: IOMMU enabled) et le remappage d’interruptions (DMAR-IR).
Décision : Si vous ne voyez pas ces lignes, ne prétendez pas que l’isolation passthrough existe. Corrigez le BIOS/args du noyau avant de diagnostiquer les performances.
Tâche 2 : Vérifier la ligne de commande du noyau pour le mode IOMMU et les pièges courants
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.8.0 root=/dev/mapper/vg0-root ro quiet intel_iommu=on iommu=pt mitigations=auto
Ce que cela signifie : intel_iommu=on l’active ; iommu=pt utilise des mappings passthrough pour les périphériques hôtes (réduit souvent le surcoût pour les périphériques non assignés).
Décision : Pour des workloads mixtes, iommu=pt est généralement sensé. Si vous déboguez l’isolation, vous pouvez temporairement l’enlever pour vérifier si le comportement change — mais documentez pourquoi.
Tâche 3 : Identifier si vous utilisez des VFs SR-IOV ou des périphériques complets
cr0x@server:~$ lspci -D | egrep -i 'ethernet|network' | head
0000:3b:00.0 Ethernet controller: Intel Corporation Ethernet Controller XXV710 for 25GbE SFP28
0000:3b:02.0 Ethernet controller: Intel Corporation Ethernet Virtual Function
0000:3b:02.1 Ethernet controller: Intel Corporation Ethernet Virtual Function
Ce que cela signifie : La PF est 3b:00.0, et des VFs existent en 3b:02.x.
Décision : Si vous attendez SR-IOV mais ne voyez que des PFs, vous n’utilisez pas SR-IOV ; vous déboguez la mauvaise chose.
Tâche 4 : Confirmer le nombre de VFs créées sur la PF
cr0x@server:~$ sudo cat /sys/class/net/enp59s0f0/device/sriov_numvfs
8
Ce que cela signifie : La PF a 8 VFs actuellement activées.
Décision : Si c’est 0, il n’y a pas de VFs. Si c’est plus que prévu, vous pouvez épuiser les ressources PF (files, TCAM, interruptions). Réduisez le nombre de VFs et retestez la stabilité.
Tâche 5 : Vérifier les groupes IOMMU pour les frontières d’isolation
cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group $(basename $g):"; ls -1 $g/devices; done | sed -n '1,40p'
Group 12:
0000:3b:00.0
0000:3b:00.1
Group 13:
0000:3b:02.0
0000:3b:02.1
Ce que cela signifie : Les périphériques dans le même groupe ne peuvent pas être isolés en toute sécurité par la plateforme.
Décision : Si votre périphérique cible partage un groupe avec quelque chose que vous ne pouvez pas passer (comme un contrôleur de stockage), n’utilisez pas le passthrough sur ce design d’hôte. Corrigez la topologie PCIe ou acceptez virtio.
Tâche 6 : Vérifier quel pilote est lié (côté hôte)
cr0x@server:~$ lspci -nnk -s 0000:3b:02.0
3b:02.0 Ethernet controller [0200]: Intel Corporation Ethernet Virtual Function [8086:154c]
Subsystem: Intel Corporation Device [8086:0000]
Kernel driver in use: vfio-pci
Kernel modules: iavf
Ce que cela signifie : La VF est liée à VFIO pour le passthrough ; le module natif VF existe mais n’est pas actif sur l’hôte.
Décision : Si vous attendiez un réseau hôte via la VF, voir vfio-pci est correct. Si vous attendiez que l’hôte l’utilise, c’est une mauvaise configuration.
Tâche 7 : Vérifier que la VM a bien le périphérique attaché (QEMU/libvirt)
cr0x@server:~$ sudo virsh domiflist vm-netperf-01
Interface Type Source Model MAC
-------------------------------------------------------
vnet0 bridge br0 virtio 52:54:00:aa:bb:cc
Ce que cela signifie : Cette VM utilise encore virtio sur un bridge, pas une VF SR-IOV en passthrough.
Décision : Arrêtez de débattre du tuning SR-IOV. Attachez d’abord le périphérique VF et confirmez les changements du driver en guest.
Tâche 8 : Vérifier la vitesse/largeur de lien PCIe négociée (cap fréquente silencieuse)
cr0x@server:~$ sudo lspci -s 3b:00.0 -vv | egrep -i 'LnkSta:|LnkCap:' | head -n 4
LnkCap: Port #0, Speed 8GT/s, Width x8
LnkSta: Speed 8GT/s, Width x4
Ce que cela signifie : La carte supporte x8 mais fonctionne en x4. C’est un problème physique/topologie/BIOS, pas un problème de driver.
Décision : Si les plafonds de débit correspondent aux limites x4, déplacez la carte, changez le riser ou corrigez la bifurcation des lanes BIOS. Ne tunez pas les files pour résoudre des lanes manquantes.
Tâche 9 : Vérifier la localité NUMA du périphérique PCI
cr0x@server:~$ cat /sys/bus/pci/devices/0000:3b:00.0/numa_node
1
Ce que cela signifie : Le périphérique est attaché au nœud NUMA 1.
Décision : Placez les vCPUs et la mémoire de la VM sur le nœud 1. Si vous ne pouvez pas, acceptez une latence plus élevée et un débit inférieur, ou déplacez le périphérique sur l’autre socket.
Tâche 10 : Trouver les IRQ des files VF et voir où elles tombent
cr0x@server:~$ grep -E 'enp59s0f0v0|iavf|vfio|msi' /proc/interrupts | head -n 8
178: 120433 0 0 0 IR-PCI-MSI 524288-edge vfio-msi[0]
179: 118901 0 0 0 IR-PCI-MSI 524289-edge vfio-msi[1]
180: 119552 0 0 0 IR-PCI-MSI 524290-edge vfio-msi[2]
Ce que cela signifie : Toutes les interruptions touchent le CPU0 (première colonne) parce que l’affinité n’est pas configurée, ou irqbalance a fait un choix « créatif ».
Décision : Épinglez les IRQs sur des CPUs locaux au NIC, et idéalement répartissez les files sur des cores isolés. Puis retestez la latence p99.
Tâche 11 : Vérifier le statut d’irqbalance (il peut aider ou nuire)
cr0x@server:~$ systemctl status irqbalance --no-pager
● irqbalance.service - irqbalance daemon
Loaded: loaded (/lib/systemd/system/irqbalance.service; enabled)
Active: active (running) since Mon 2026-02-02 09:14:12 UTC; 1 day ago
Ce que cela signifie : irqbalance tourne et peut déplacer dynamiquement les IRQs.
Décision : Pour les workloads sensibles à la latence SR-IOV/passthrough, envisagez de désactiver irqbalance et de définir explicitement l’affinité — surtout sur des hôtes avec isolation CPU.
Tâche 12 : Vérifier la configuration hugepages (hôte)
cr0x@server:~$ grep -i huge /proc/meminfo | head -n 6
HugePages_Total: 2048
HugePages_Free: 1980
HugePages_Rsvd: 12
Hugepagesize: 2048 kB
Hugetlb: 4194304 kB
Ce que cela signifie : Des hugepages 2M sont disponibles et majoritairement libres.
Décision : Si vous chassez le surcoût IOMMU/IOTLB, les hugepages sont un levier. Si HugePages_Free est bas, vous pourriez fragmenter ou fuir des réservations ; corrigez avant de blâmer SR-IOV.
Tâche 13 : Vérifier si la VM utilise des hugepages (libvirt)
cr0x@server:~$ sudo virsh dumpxml vm-netperf-01 | egrep -n 'memoryBacking|hugepages|locked'
112:
113:
114:
115:
Ce que cela signifie : La mémoire VM est backed par des hugepages et verouillée (réduit le churn de pages et les surprises).
Décision : Si vous utilisez SR-IOV/passthrough et tenez à la latence de queue, c’est généralement utile. Si vous ne pouvez pas lock la mémoire, attendez-vous à de la variabilité sous pression hôte.
Tâche 14 : Vérifier les fautes IOMMU (vous seriez étonné)
cr0x@server:~$ dmesg | egrep -i 'DMAR:.*fault|IOMMU.*fault|AMD-Vi:.*Event' | tail -n 10
[12345.671234] DMAR: [DMA Read] Request device [3b:02.0] fault addr 0x7f3a1000 [fault reason 0x05] PTE Read access is not set
Ce que cela signifie : Le périphérique a tenté un DMA en dehors des mappings autorisés, ou des mappings sont démontés incorrectement.
Décision : Stop. Ce n’est pas un problème de tuning ; c’est un problème de correction. Vérifiez les versions VFIO/QEMU, bugs de drivers, et si vous débranchez des périphériques à chaud de façon non sûre.
Tâche 15 : Vérifier les offloads NIC dans le guest (les VFs SR-IOV varient)
cr0x@server:~$ sudo ethtool -k ens5 | egrep -i 'rx-checksumming|tx-checksumming|tso|gso|gro|lro'
rx-checksumming: on
tx-checksumming: on
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
Ce que cela signifie : Les offloads sont activés comme attendu ; LRO est off (souvent bon pour la latence/observabilité).
Décision : Si des offloads sont inattendument désactivés, vous paierez en CPU. S’ils sont activés mais que vous voyez des traces de paquets étranges, envisagez de désactiver GRO pour le diagnostic — pas comme « fix » permanent.
Tâche 16 : Vérifier l’anti-spoofing et les réglages de trust des VF sur la PF (hôte)
cr0x@server:~$ sudo ip link show enp59s0f0
2: enp59s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 3c:fd:fe:aa:bb:cc brd ff:ff:ff:ff:ff:ff
cr0x@server:~$ sudo ip link show enp59s0f0 vf 0
vf 0 MAC 52:54:00:11:22:33, vlan 100, spoof checking on, link-state auto, trust off, query_rss on
Ce que cela signifie : La VF a VLAN appliqué, spoof checking activé, trust off. C’est un bon défaut pour des environnements partagés.
Décision : Si trust on apparaît « parce que ça a corrigé quelque chose », exigez une raison concrète et ajoutez des contrôles compensatoires. Le trust a tendance à se propager comme de la moisissure.
Tâche 17 : Confirmer le gouverneur de fréquence CPU/état d’alimentation (cause fréquente de tail latency)
cr0x@server:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
powersave
Ce que cela signifie : Le CPU peut se déclock agressivement, nuisant à la latence p99.
Décision : Pour des hôtes dataplane haute performance, utilisez le gouverneur performance ou un tuning plateforme adapté. Si vous ne pouvez pas, cessez d’espérer une latence déterministe.
Tâche 18 : Vérifier la pression softirq (santé du dataplane réseau)
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0 (server) 02/04/2026 _x86_64_ (32 CPU)
02:11:01 PM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
02:11:02 PM all 12.5 0.0 9.8 0.0 2.1 18.7 0.0 56.9
Ce que cela signifie : Un %soft élevé suggère que le traitement softirq est lourd ; commun dans les workloads à fort trafic de paquets.
Décision : Ajoutez des files/cores, améliorez l’affinité IRQ/RPS/XPS, ou migrez vers SR-IOV/DPDK si virtio est le goulot. Si vous êtes déjà sur SR-IOV, cela pointe vers le steering et le placement CPU.
Trois mini-récits d’entreprise depuis le terrain
Mini-récit 1 : L’incident causé par une fausse hypothèse
Ils déployaient le passthrough NIC pour un service sensible à la latence. Le pitch était propre : « supprimez le switch virtuel, réduisez l’overhead, baissez le p99 ». L’hôte de test allait bien. Le canari allait bien. Puis la production a… été hantée.
Un cluster a commencé à redémarrer sous charge. Pas tous les nœuds. Seulement ceux d’une rangée de rack particulière. Les logs montraient des faults DMA sporadiques et parfois un lockup brutal sans panic noyau propre. L’équipe a d’abord pensé au classique : « bug de driver ». Ils ont mis à jour les drivers invités. Ils ont mis à jour QEMU. Ils ont désactivé des offloads. Les hantises ont continué.
L’hypothèse erronée était que « IOMMU activée dans le BIOS » signifiait « IOMMU fonctionne réellement de bout en bout ». Sur les nœuds affectés, le réglage BIOS était présent mais la plateforme était livrée avec le remappage d’interruptions désactivé à cause d’un firmware ancien. Linux a activé le remappage DMA mais n’a pas pu activer proprement le remappage d’interruptions sur cette révision matérielle.
Ils passaient un périphérique qui spammait des interruptions MSI-X sous charge maximale, et sans garanties de remappage correctes, la plateforme se comportait de façon imprévisible. Ce n’était pas que l’IOMMU « était off » ; c’était qu’une tranche critique n’était pas fiable.
La correction a été ennuyeuse : standardiser les profils BIOS, ajouter un gate au démarrage qui échoue le nœud si DMAR-IR n’est pas activé, et refuser la programmation de passthrough sur ces hôtes. Les performances se sont améliorées plus tard, mais l’incident a fini parce qu’ils ont cessé de se mentir sur les capacités de la plateforme.
Mini-récit 2 : L’optimisation qui s’est retournée contre eux
Une autre entreprise utilisait des VFs SR-IOV pour des workloads haut débit. Quelqu’un a remarqué que le surcoût de traduction IOMMU pouvait contribuer au coût CPU à des PPS extrêmes. Ils ont trouvé iommu=pt et décidé de « optimiser » encore : désactiver l’IOMMU pour l’hôte, parce que « les guests n’ont que des VFs et le NIC les isole de toute façon ».
Au début ça semblait gagnant. Les microbenchmarks s’amélioraient légèrement, et les graphes CPU semblaient plus propres. Puis le vrai workload a frappé : corruption de données sporadique dans un service soutenu par du stockage qui utilisait aussi un autre périphérique en passthrough sur certains nœuds. Pas partout — seulement lorsque l’ordonnancement alignait une combinaison particulière d’assignation de périphérique et de pression mémoire.
Sans IOMMU, un périphérique défaillant (ou une interaction buggy) pouvait DMA dans une mémoire qu’il ne devait pas toucher. La corruption n’était pas bruyante. Elle était subtile : erreurs de checksum rares, crashes de processus occasionnels, transitions d’état « impossibles ». Le pire type d’incident : celui qui fait douter votre équipe des lois de la physique.
Ils ont reverté le changement et la corruption a cessé. Le postmortem n’a pas été indulgent : l’optimisation chassait un surcoût théorique tout en supprimant la barrière de sécurité. Le coût du « gain » a été des jours de réponse à incident, revues de risque, et une nouvelle politique : l’IOMMU reste activé ; si la performance est un problème, corrigez la stratégie de mapping (hugepages, pinning) ou changez le design dataplane.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une équipe plateforme gérait une flotte mixte : des hôtes pour virtualisation générique (virtio partout), et une plus petite piscine pour SR-IOV haute performance et passthrough GPU occasionnel. Ils avaient la réputation d’être irritablement stricts sur les profils d’hôte.
À chaque démarrage ils exécutaient une checklist : valider IOMMU activé, valider remappage d’interruptions, valider largeur de lien NIC, valider versions firmware contre une allowlist, valider comptes de VF, valider contraintes NUMA. Si un contrôle échouait, le nœud était drainé automatiquement. Pas d’héroïsme. Pas de négociation.
Un jour, une série de serveurs est arrivée avec une différence subtile de topologie PCIe. Le NIC a négocié x4 au lieu de x8 dans une configuration de slot. Rien n’« a cassé ». Aucun alert du driver NIC. Les applications sont simplement devenues plus lentes d’une manière qui ressemblait à un « pic de trafic ».
Le gate de boot l’a détecté : LnkSta ne correspondait pas aux attentes. Les nœuds n’ont jamais rejoint la piscine SR-IOV. Les workloads sont restés sur des hôtes sains, et le seul « incident » a été un ticket ops pour déplacer les cartes dans les bons slots.
La pratique qui les a sauvés n’était pas un tweak kernel clever. C’était le refus d’accepter une dégradation silencieuse. Le reliability engineering consiste surtout à décider ce que vous ne tolérerez pas.
Erreurs courantes : symptômes → cause racine → correction
1) Symptôme : « Le passthrough est activé, mais les performances sont pires que virtio »
Cause racine : La VM est en remote-NUMA par rapport au périphérique ; les interruptions tombent sur les mauvais CPUs ; mémoire non pinée ; churn IOTLB dû à mémoire fragmentée.
Correction : Alignez vCPUs et mémoire sur le nœud NUMA du NIC, activez hugepages + mémoire verouillée, définissez l’affinité IRQ, adaptez le nombre de files aux cœurs.
2) Symptôme : « La VF SR-IOV perd le lien ou se bloque aléatoirement sous charge »
Cause racine : Bug du pilote PF/firmware déclenché par le compte de VFs, le nombre de files, ou une combinaison d’offloads ; parfois aggravé par des resets.
Correction : Mettez à jour le firmware NIC + le pilote PF ; réduisez VFs/files ; évitez des combos d’offloads exotiques ; ajoutez des health checks recréant les VFs en cas d’échec.
3) Symptôme : « VFIO attach échoue : device busy / can’t reset »
Cause racine : Le périphérique est lié au driver hôte ou fait partie d’un groupe avec d’autres fonctions en usage ; limitations FLR/reset.
Correction : Désassociez proprement, assurez l’isolation par groupe IOMMU, évitez de passer des périphériques sans sémantique de reset fiable, ou utilisez SR-IOV à la place.
4) Symptôme : « Les groupes IOMMU sont énormes ; impossible d’isoler le NIC »
Cause racine : La topologie PCIe manque d’ACS, ou les périphériques partagent des composants en amont qui ne peuvent pas appliquer l’isolation.
Correction : Changez l’emplacement/la topologie du slot, utilisez des hôtes avec des switches ACS-capables, ou cessez d’essayer le passthrough sûr sur cette plateforme.
5) Symptôme : « Latence p99 élevée seulement lors de la contention hôte »
Cause racine : Fréquence CPU variable, migration d’IRQ, reclaim mémoire, ou voisins bruyants sur le même socket.
Correction : Isolation CPU pour cœurs dataplane, gouverneur performance, désactiver irqbalance (ou le configurer), réserver hugepages, verrouiller la mémoire, définir des politiques NUMA réelles.
6) Symptôme : « Des paquets sont perdus dans le guest, l’hôte a l’air OK »
Cause racine : Famine des files VF, tailles de ring insuffisantes, modulation d’interruption trop agressive, ou driver invité mal réglé.
Correction : Augmentez les tailles de ring, ajustez la coalescence, assurez MSI-X, assurez assez de files, pinnez les vCPUs, et validez la version du driver invité.
7) Symptôme : « L’équipe sécurité dit que SR-IOV est dangereux »
Cause racine : Politiques VF trust/spoof/VLAN laissées permissives ; mauvaise compréhension du risque lié au matériel partagé.
Correction : Appliquez les politiques VF sur la PF, restreignez les fonctionnalités par locataire, auditez l’assignation de périphériques, assurez l’IOMMU activé, documentez le modèle de menace.
Checklists / plans pas à pas
Checklist A : Choisir SR-IOV vs passthrough (décision, pas impressions)
- Besoin de partage de périphérique entre plusieurs guests ? SR-IOV. Si le périphérique ne supporte pas bien SR-IOV, reconsidérez le matériel.
- Besoin des fonctionnalités complètes du périphérique (GPU, modes avancés HBA, outils vendor) ? Passthrough.
- Besoin de migration à chaud/snapshots ? Préférez virtio. SR-IOV/passthrough compliquent ou bloquent cela.
- Tolérance au risque multi-tenant faible ? Passthrough avec IOMMU et contrôles plateforme stricts, ou évitez totalement l’assignation de périphérique.
- Maturité ops : Si vous ne pouvez pas standardiser BIOS/firmware/versions noyau, ne faites pas d’assignation de périphérique à grande échelle.
Checklist B : Plan de déploiement SR-IOV (ordre des opérations)
- Standardiser les réglages BIOS (VT-d/AMD-Vi on, SR-IOV on, réglages PCIe cohérents).
- Standardiser la cmdline noyau et valider via des gates
dmesg. - Choisir un nombre de VFs par PF basé sur les limites hardware et les besoins en files (ne pas tout mettre par défaut au max).
- Définir la politique VF : spoof checking on, trust off par défaut, politique VLAN explicite.
- Définir une politique de placement NUMA pour les hôtes SR-IOV et l’appliquer via l’ordonnanceur.
- Implémenter une stratégie d’affinité IRQ ; ne comptez pas sur la chance.
- Canary sous vrais motifs de trafic (PPS + tailles de paquets + nombre de flux).
- Observer p99/p999, drops, resets, et fautes IOMMU ; avancer seulement quand c’est ennuyeux.
Checklist C : Plan de déploiement Passthrough (ne pas cramer votre hôte)
- Vérifier que l’IOMMU et le remappage d’interruptions sont activés et stables sur reboots.
- Vérifier les groupes IOMMU et assurer que le périphérique peut être isolé.
- Vérifier le support de reset du périphérique (FLR ou comportement vendor) fonctionne de façon fiable.
- Binder le périphérique à
vfio-pciet confirmer que les services hôtes n’en auront pas besoin. - Pinnez vCPUs et mémoire de la VM sur le nœud NUMA du périphérique ; utilisez des hugepages si la gigue vous concerne.
- Instrumenter : collecter les fautes IOMMU dans
dmesg, erreurs PCIe AER, et métriques de distribution d’interruptions. - Avoir un rollback : détacher le périphérique, le rebinder au driver hôte, restaurer les chemins réseau/stockage.
FAQ
1) SR-IOV est-il toujours plus rapide que virtio ?
Non. SR-IOV réduit souvent le CPU par paquet et améliore le débit, mais peut perdre sur la latence de queue si IRQ/NUMA/mapping mémoire sont négligés. Virtio peut être « assez rapide » et bien plus simple à exploiter.
2) Le passthrough est-il toujours l’option la plus rapide ?
Souvent pour la possession d’un périphérique par un seul locataire, oui. Mais « le plus rapide » dépend du placement et du traitement des interruptions. Un périphérique passthrough en remote-NUMA peut être plus lent qu’un chemin virtio bien tuné.
3) Ai-je besoin d’IOMMU pour SR-IOV ?
Si vous assignez des VFs aux guests, vous voulez l’IOMMU pour l’isolation DMA. Si tout reste sur l’hôte, c’est moins une question d’isolation — mais de nombreuses plateformes se comportent mieux avec une configuration IOMMU cohérente.
4) Que fait iommu=pt exactement ?
Il met typiquement en place des mappings identité/pass-through pour les périphériques hôtes afin qu’ils ne paient pas le surcoût de traduction, tout en permettant des mappings traduits pour les périphériques assignés. C’est un compromis courant entre performance et sécurité.
5) Pourquoi mes groupes IOMMU sont-ils « trop grands » ?
Parce que votre matériel ne peut pas isoler ces périphériques les uns des autres. La topologie PCIe et le support ACS déterminent le grouping. Linux rapporte la frontière qu’il peut faire confiance, pas celle que vous souhaiteriez avoir.
6) Puis-je migrer à chaud une VM utilisant SR-IOV ou passthrough ?
Pas de la façon habituelle « ça marche tout seul ». L’assignation de périphérique lie la VM à un état matériel spécifique. Certains écosystèmes ont des approches spécialisées de migration, mais traitez cela comme un projet spécial, pas une case à cocher.
7) Quelle est la cause principale des rapports « SR-IOV est instable » ?
Incompatibilité firmware/driver et sur-allocation des ressources sur le NIC (trop de VFs, trop de files, réglages trop agressifs). La deuxième cause est opérationnelle : VFs non recréées correctement après reboot ou événements de lien.
8) L’IOMMU ajoute-t-il une latence mesurable ?
Oui, potentiellement, surtout quand les mappings churnent ou que les misses IOTLB augmentent. Avec mémoire pinnée, hugepages et mappings stables, le surcoût est souvent faible comparé au reste du dataplane.
9) Dois-je désactiver irqbalance sur les hôtes SR-IOV/passthrough ?
Pour les workloads sensibles à la latence, oui — sauf si vous avez explicitement configuré irqbalance pour respecter l’isolation et la localité. La migration dynamique d’IRQ et la p99 déterministe ne sont pas amis.
10) Quelle est l’architecture « safe default » la plus simple ?
Virtio pour le calcul général, une piscine SR-IOV séparée pour les workloads performance, et passthrough uniquement pour les périphériques nécessitant vraiment une pleine possession. Gardez des profils hôtes stricts et validés.
Étapes pratiques suivantes
Décidez en fonction de votre réalité opérationnelle, pas de la capture d’écran d’un benchmark.
- Choisissez une base : Si vous êtes actuellement sur virtio, rectifiez d’abord l’hygiène NUMA/IRQ. Sinon vous ne saurez pas ce que SR-IOV a amélioré.
- Activez correctement l’IOMMU : Confirmez le remappage DMA et le remappage d’interruptions dans
dmesg. Gatez votre flotte là-dessus. - Choisissez le bon modèle : SR-IOV pour l’accélération NIC partagée, passthrough pour la possession de périphérique mono-locataire, virtio pour la flexibilité.
- Opérationnalisez : Standardisez firmware, BIOS, args noyau, comptes de VF et politique de sécurité VF. Automatisez les contrôles ; drenez en cas de mismatch.
- Mesurez ce qui compte : Suivez la latence p99/p999 et les pertes, pas seulement le débit moyen. La plupart des incidents vivent dans les queues.
Une citation à garder sur un post-it, parce qu’elle résume le travail : « L’espoir n’est pas une stratégie. » — General Gordon R. Sullivan