Ce qu’est le MPS

Les équipements PCIe transfèrent les données dans des paquets appelés Transaction Layer Packets (TLP). Chaque TLP a un en-tête et une charge utile. La taille maximale de cette charge utile est la MaxPayloadSize (MPS).

Le MPS est négocié entre un équipement et son pont amont pendant l’entraînement du lien. La valeur négociée est la plus petite entre ce que l’équipement gère et ce que le pont autorise. Chaque pont et chaque switch sur le chemin entre l’équipement et le root complex a sa propre capacité MPS. Le MPS final d’un équipement est fixé par le point le plus étroit de la chaîne.

Les valeurs courantes de MPS sont 128, 256 et 512 octets. Certains équipements gèrent 1024 voire 4096 octets, mais en pratique 256 ou 512 est la norme pour les contrôleurs NVMe et les cartes réseau. Les GPU gèrent souvent 256 octets.

Pourquoi ça compte

Un MPS plus grand, c’est moins de paquets pour la même quantité de données. Une E/S de 4 Kio transférée à MPS 128 demande 32 TLP. Le même transfert à MPS 512 en demande 8.

Chaque TLP transporte une surcharge de protocole — l’en-tête, le CRC, le tramage. Moins de TLP, c’est moins de surcharge de protocole par octet transféré. À haut débit, cette différence est mesurable. Pas spectaculaire. Mais réelle. Et c’est la même surcharge, payée sur chaque paquet.

Le MPS influe aussi sur la façon dont le lien PCIe est utilisé. Des charges utiles plus petites font passer au lien plus de temps sur les en-têtes que sur les données. Des charges utiles plus grandes déplacent le rapport vers les données utiles.

La même charge utile de 4 Kio coûte 32 en-têtes de paquet à MPS 128 et 8 à MPS 512MPS 128 — un transfert de 4 Kio devient 32 TLP32 en-têtes × ≈24 o — ≈16 % des octets sur le fil sont de la surchargeMPS 512 — les mêmes 4 Kio deviennent 8 TLP8 en-têtes × ≈24 o — ≈4 % des octets sur le fil sont de la surchargeen-tête, numéro de séquence, CRC et tramagecharge utileLes deux bandes portent les mêmes 4 Kio. Une charge utile plus grande ne déplace pasplus de données — elle passe moins de temps à la décrire. Le gain mesuré est faible.
Les deux bandes transportent les mêmes 4 Kio. Les barres pleines sont les en-têtes par paquet — à MPS 128 il y en a 32, à MPS 512 seulement 8.

L’impact sur la latence est plus faible que sur le débit. Une seule lecture de 4 Kio à MPS 128 contre 512 ne montrera pas d’écart de latence digne d’être mesuré, parce que les TLP sont pipelinés. Mais poussez de forts IOPS avec beaucoup de transferts en vol et la surcharge moindre d’un MPS plus grand finit par compter.

Le problème sous passthrough

Sur du matériel nu, le BIOS règle le MPS pendant le POST en fonction de la topologie PCIe. Un BIOS serveur moderne règle en général le MPS au maximum que la topologie supporte, souvent 256 ou 512 octets.

Sous QEMU, le root complex du chipset Q35 virtuel a sa propre capacité MPS. Par défaut, il présente un MPS bas. La politique MPS par défaut du noyau Linux (pcie_bus_default) règle le MPS de chaque équipement sur celui de son pont parent, ce qui dans une topologie virtuelle veut dire la valeur par défaut du root complex de QEMU. Souvent 128 octets.

Du coup, un équipement capable de charges utiles de 512 octets tourne à 128 parce que le root complex virtuel a fixé le plafond.

Le MPS est fixé par le point le plus étroit du chemin, qui sous QEMU est le root complex virtuelMatériel nu — le BIOS règle le MPS d'après la topologie réelleNVMegère 512Switch PCIeautorise 512Root complexautorise 512MPS = 512 ole plus petit du cheminPassé à une VM — le root complex virtuel est désormais le point le plus étroitNVMegère 512Root complex virtuel QEMU Q35présente 128 par défautMPS = 128 ocapacité de l'équipement inutiliséeNoyau hôte avec pci=pcie_bus_perfNVMegère 512chaque équipement au maximum de son bus parentMRRS relevé en conséquenceMPS = 512 oréglé sur l'hôte, pas sur l'invité
Le MPS est la plus petite valeur du chemin. Passer un équipement en passthrough insère le root complex virtuel dans ce chemin, et sa valeur par défaut prudente devient le plafond de tout le monde.

Comment corriger — côté hôte

Dites au noyau de régler le MPS au maximum que le bus parent de chaque équipement supporte :

# Add to GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub
pci=pcie_bus_perf

Ceci règle le MPS de chaque équipement sur la plus grande valeur que son bus parent autorise. Ça règle aussi le MRRS (Max Read Request Size) en conséquence. Le source du noyau dit que ça garantit que le MPS d’un équipement ne dépasse pas celui de son parent. Ça garde la chaîne cohérente tout en obtenant les meilleures tailles de transfert.

Après redémarrage, vérifiez le nouveau MPS :

# Check MPS on a specific device
lspci -vv -s XX:00.0 | grep -i "MaxPayload"

Vous devriez voir MaxPayload 256 bytes ou MaxPayload 512 bytes au lieu du 128 par défaut.

Les autres options du noyau

Le noyau propose quatre politiques MPS, chacune réglée par le paramètre de démarrage pci= :

pcie_bus_tune_off — ne pas toucher au MPS du tout. On garde ce que le BIOS a réglé. Sur du matériel nu avec un bon BIOS, c’est souvent très bien. Sous QEMU, le BIOS est OVMF ou SeaBIOS, qui n’optimisent pas forcément le MPS.

pcie_bus_default — la valeur par défaut du noyau. Règle le MPS de chaque équipement sur celui de son pont amont. Prudent et sûr, mais ne maximise pas les performances.

pcie_bus_safe — règle le MPS sur la plus grande valeur supportée par tous les équipements du système. Utile pour les systèmes fermés où vous connaissez tous les équipements et où rien ne sera branché à chaud. Un peu plus agressif que le défaut.

pcie_bus_perf — règle le MPS équipement par équipement sur la plus grande valeur que le bus parent autorise. Chaque équipement obtient le meilleur MPS que sa topologie locale supporte. C’est le bon choix pour le passthrough parce qu’il optimise chaque chemin indépendamment.

pcie_bus_peer2peer — règle le MPS à 128 octets sur tout. Tous les équipements se parlent à la plus petite taille commune. S’utilise quand des équipements doivent faire du DMA directement entre eux (GPU vers GPU, GPU vers carte réseau via RDMA). Sans intérêt pour un passthrough classique.

pcie_bus_perf est le bon pour le passthrough.

Comment corriger — côté invité

Vous pouvez aussi mettre pci=pcie_bus_perf dans la configuration de démarrage du noyau invité. Que ça ait un effet pratique dépend de la façon dont QEMU présente la topologie PCIe virtuelle. Le root complex virtuel plafonne ce que l’invité peut négocier.

À l’usage, c’est la correction côté hôte qui tient. L’hôte possède l’équipement physique, et son réglage MPS fixe la taille réelle des TLP sur le fil. Le réglage de l’invité ne touche que la topologie virtuelle dans la VM, et savoir si ça change le comportement réel dépend de la façon dont QEMU présente le chemin PCIe pour cet équipement.

Réglez-le sur l’hôte. Le régler aussi dans l’invité ne fera pas de mal, mais ne comptez pas dessus seul.

Ce qu’est le MRRS

La Max Read Request Size (MRRS) est liée mais distincte. Le MPS limite la quantité de données qu’un équipement peut envoyer dans un TLP. Le MRRS limite la quantité de données qu’un équipement peut demander dans une requête de lecture.

Un équipement avec un MRRS de 4096 peut émettre une seule requête de lecture de 4 Kio. La réponse revient en plusieurs TLP, chacun d’au plus la taille du MPS. Un MRRS plus élevé veut dire que l’équipement peut demander plus de données par transaction, ce qui réduit le nombre de TLP de requête de lecture sur le bus.

Le MRRS dimensionne la requête, le MPS dimensionne chaque paquet de la réponseContrôleur NVMeMRRS 4096 omémoire hôtevia le root complex1 × requête de lecture — « envoie-moi 4 Kio »Le MRRS plafonne ce qu'une requête peut demander8 × TLP d'achèvement — 512 o chacunLe MPS plafonne la taille de chaque paquet de la réponseUne requête, beaucoup de paquets. pci=pcie_bus_perf relève les deux, inutile de les régler séparément.
Les deux sont faciles à confondre : le MRRS limite ce qu’un équipement peut demander en une requête, le MPS limite la taille de chaque paquet de la réponse.

pci=pcie_bus_perf règle à la fois le MPS et le MRRS à leurs valeurs optimales. Vous n’avez pas besoin de les régler séparément.

Face aux autres réglages

L’écart de MPS entre 128 et 512 octets a moins d’impact sur les performances que l’alignement NUMA ou l’ASPM. C’est typiquement une amélioration de débit de quelques pour cent. Vous ne le verrez pas dans des tests de latence à faible profondeur de file.

Mais c’est une optimisation gratuite. Un paramètre noyau, aucun inconvénient, aucun risque de compatibilité. Il n’y a aucune raison de ne pas le régler sur un système qui fait du passthrough.

Ça ne coûte rien, et vous avez déjà payé le matériel. Autant avoir ce que vous avez acheté.

Références