
Proxmox ARM64 auf dem ASUS GX10: Vom 6.3 GB/s Engpass zum vollen Durchsatz
Auf einem ASUS GX10 unter Proxmox VE 9.2 ARM64 stieg der NVMe/TCP-Lese-Durchsatz des Kernels nach Optimierungen an IOMMU, PCIe, NIC und Queue-Handling von 6.3 GB/s auf 28.1 GB/s an. Es handelt sich hierbei um Host-Level-Benchmarks auf einem spezifischen Testaufbau, nicht um pauschale Aussagen über allgemeine VM-Leistung oder KI-Inferenz.
Der veröffentlichte Testbericht von Blockbridge erläutert die schrittweise Steigerung: Der Parameter iommu.strict=0 brachte den Kernel-Initiator zunächst auf 24.4 GB/s, die Option pci=pcie_bus_perf steigerte den Wert auf 26.5 GB/s, und ergänzendes Netzwerk-Tuning führte schließlich zum Ergebnis von 28.1 GB/s. Mit SPDK ermittelte das Team parallel dazu sogar einen Spitzenwert von 28.9 GB/s.
Warum stockte NVMe/TCP auf dem ASUS GX10 bei 6.3 GB/s?
Das veröffentlichte Testergebnis führt den niedrigen Standard-Lesedurchsatz vor allem auf die strikte IOMMU-Invalidierung in der geprüften Hostkonfiguration zurück.
Das Datenblatt des GX10 lässt für ein kompaktes System aufhorchen: zwanzig Arm CPU-Kerne (ARM64), 128 GB Arbeitsspeicher, eine GPU und ein Dual-Port 200 Gb/s NVIDIA ConnectX-7 Netzwerkadapter. NVMe over TCP ermöglicht den Zugriff auf entfernten NVMe-Storage über gewöhnliche Ethernet-Netzwerke; dadurch stellt es einen hervorragenden Härtetest für den gesamten Empfangspfad dar, anstatt bloß isolierte Spitzenwerte eines einzelnen Chips zu demonstrieren. Die Datenpakete treffen an der NIC ein, passieren den PCIe-Bus, durchlaufen die IOMMU-Übersetzung und landen schließlich im Host-Speicher. Ein Engpass an einer beliebigen Stelle dieser Kette bremst die gesamte Übertragungsrate aus.
Hintergründe zum Zusammenspiel von KVM und virtuellen Geräten finden Sie in unserer Gegenüberstellung von QEMU und KVM in Proxmox.
Der Verfasser wies transparent darauf hin, bei Blockbridge zu arbeiten, dem Hersteller des im Test eingesetzten NVMe/TCP-Storage-Targets. Der technische Bericht liefert die exakten Konfigurationen und Testbefehle. Die Tester passten Host-Einstellungen schrittweise an, verglichen den Kernel-Initiator mit SPDK und prüften die Messwerte anhand der rechnerischen Bandbreitenkapazität der PCIe-Verbindungen.
Zu Beginn war der Kontrast dramatisch: Der Kernel-Initiator lieferte magere 6.3 GB/s, während SPDK auf derselben unveränderten Hardware bereits 21.3 GB/s erzielte. Ein Profiling lieferte den entscheidenden Hinweis: Die Funktion arm_smmu_cmdq_issue_cmdlist beanspruchte 57% aller CPU-Zyklen auf den größeren Kernen. Das System verbrauchte unverhältnismäßig viel Rechenzeit allein für die Abwicklung von IOMMU-Befehlen. Der Engpass lag eindeutig im IOMMU-Overhead.
Welche Kernel-Parameter verbesserten den Durchsatz des GX10?
Die Optionen iommu.strict=0 und pci=pcie_bus_perf lösten zwei getrennte Flaschenhälse; das Erreichen von 28.1 GB/s erforderte darüber hinaus weitere Anpassungen an der Netzwerkkarte.
Der erste Hebel war iommu.strict=0. Im getesteten ARM64-Kernel zwang die strikte IOMMU-Invalidierung jeden DMA-Unmap-Vorgang dazu, auf die Invalidierung des Hardware-Übersetzungscaches zu warten. Bei einer SMMU mit einer einzelnen Befehlswarteschlange führten diese Blockaden zu drastischen Wartezeiten. Die Umstellung auf verzögerte Invalidierung (Lazy Mode) erlaubte die Bündelung von Operationen, was den Kernel-Initiator von 6.3 auf 24.4 GB/s katapultierte. SPDK verbesserte sich zeitgleich von 21.3 auf 24.7 GB/s. Das verdeutlicht, wie unterschiedlich beide Software-Pfade auf diesen Engpass reagierten.
Als Nächstes folgte pci=pcie_bus_perf. Die GX10-Firmware hatte die PCIe-Root-Ports der Netzwerkkarte mit einer maximalen Payload-Größe von 128 Bytes initialisiert, obwohl die Hardware 512 Bytes beherrscht. Linux behielt die restriktive Vorgabe standardmäßig bei, wodurch wertvolle Buskapazität verschenkt wurde. Der performanceorientierte PCIe-Parameter aktivierte die größere Payload-Größe, womit der Kernel-Initiator 26.5 GB/s und SPDK 28.8 GB/s erreichten. Ergänzend aktivierte das Team Large Receive Offload (LRO), senkte die Anzahl ausstehender Lesevorgänge und band NIC-Interrupts fest an CPU-Kerne. Diese Feinabstimmungen hoben die Durchschnitte auf 28.1 bzw. 28.9 GB/s. Die eingängige Geschichte zweier magischer Bootflags beschreibt zwar den Durchbruch treffend, doch das Endergebnis spiegelt eine ganzheitliche Systemabstimmung wider.
Die physikalischen Grenzen erklären, warum die letzten Gigabyte hart erkämpft werden mussten: Hinter der ConnectX-7 Karte liegen zwei getrennte PCIe Gen5 x4 Verbindungen (PCIe 5 x4) und keine durchgehende x16 Anbindung. Das Team errechnete ein maximales theoretisches NVMe-Nutzdatenlimit von rund 29.9 GB/s. Das Erreichen von 28.9 GB/s ist in Relation zu dieser Topologie herausragend, stellt aber keinen Freifahrtschein für unendliche Bandbreite dar. Ein besonders günstiger SPDK-Durchlauf erreichte kurzzeitig 29.3 GB/s Nutzdaten; die Tester betonten jedoch, dass solche Spitzenwerte nicht reproduzierbar waren, da sich TCP-Verbindungen mitunter ungleichmäßig über die Empfangswarteschlangen der NIC verteilten. Selbst nahe am Hardware-Limit bleiben Paketverteilung und CPU-Scheduling entscheidend.
Wie schränkte die ConnectX-7-Topologie den GX10 ein?
Die ConnectX-7 verteilt ihre Verbindungen über zwei PCIe Gen5 x4 Links; der Datenverkehr muss daher gezielt über die passenden Physical Functions (PF) geleitet werden.
Eine Dual-Port-NIC wirkt auf den ersten Blick wie zwei getrennte, logische Schnittstellen. Auf diesem GX10 erwies sich diese Annahme als trügerisch: Jeder der beiden physischen Ports stellte jeweils eine Physical Function auf beiden PCIe-Hälften bereit, sodass Linux vier PFs vorfand. Eine gegebene PF konnte stets nur ihren eigenen x4 Link nutzen; zwei PFs auf derselben PCIe-Hälfte teilten sich somit das gemeinsame Limit von ca. 14.8 GB/s. Wurde der gesamte Datenverkehr nur über einen einzelnen physischen 200 Gb/s Port geleitet, griff dessen Schnittstellenlimit von etwa 24.7 GB/s. Um die gemessenen 28.9 GB/s zu erreichen, mussten alle 4 PFs parallel angesprochen werden, damit beide physischen Ports und beide PCIe-Hälften gleichzeitig Daten übertrugen. Die tatsächliche Bandbreite ergab sich aus dem konkreten Paketpfad, nicht aus den Werbeversprechen auf der Verpackung.
Storage-Tuning greift nur dann optimal, wenn die Speicherarchitektur exakt zum Workload passt; ein Thema, das unser Vergleich von ZFS, Ceph und LVM in Proxmox ausführlich beleuchtet.
Hinzu kam ein tückisches ARP-Phänomen: Zwei PFs, die sich einen physischen Port teilen, beantworteten unter Standard-Linux-Konfigurationen ARP-Anfragen gegenseitig. Je nachdem, welche Antwort das Gegenüber zuerst erreichte, floss der gesamte Rückverkehr plötzlich über eine einzige Verbindung, während die andere brachlag. Es gab keine Fehlermeldungen, und die Verbindungsanzeige signalisierte volle Bandbreite. Den einzigen verlässlichen Anhaltspunkt lieferte der Counter rx_bytes der einzelnen PFs. Die Kernel-Einstellungen arp_ignore=1 und arp_announce=2 lösten dieses Verhalten im Testaufbau zuverlässig.
Ein Blick auf das Monitoring-Interface der Tester brachte ein weiteres interessantes Detail ans Licht: Das Dashboard basierte auf einem maßgeschneiderten Python-Skript mit der Rich-Bibliothek und aggregierte Daten aus /proc, /sys und ethtool. Es stellte Netzwerk-, PCIe- und NVMe-Durchsatz zusammen mit der Kern-Auslastung dar, wodurch Engpässe sofort sichtbar wurden. Maßgeschneiderte Instrumentierung ist bei unkonventioneller Hardware oft der einzige Weg zu echten Erkenntnissen.
Sollten Sie verzögerte IOMMU-Invalidierung auf Proxmox nutzen?
iommu.strict=0 kann den Durchsatz dramatisch anheben; der Linux-Kernel weist jedoch ausdrücklich darauf hin, dass dies zulasten der Geräteisolation geht.
Der stärkste Einwand betraf den Sicherheitsaspekt von iommu.strict=0: Ein Kommentator sah darin den bekannten Tausch von Sicherheit gegen Geschwindigkeit. Die Tester wiesen diese Bedenken keineswegs zurück, stellten jedoch klar: Lazy Invalidation deaktiviert die IOMMU-Übersetzung nicht. Adressübersetzungen bleiben aktiv; der Unterschied liegt im Zeitpunkt, zu dem veraltete Cache-Einträge nach einem DMA-Unmap gelöscht werden. Die gebündelte Löschung spart viel Zeit, kann jedoch im Nanosekundenbereich dazu führen, dass ein Gerät kurzzeitig auf Speicherbereiche zugreifen könnte, die der Kernel intern bereits freigegeben hat. Die offizielle Dokumentation zu Kernel-Parametern führt diesen Parameter explizit als Trade-off zwischen Durchsatz und Isolation auf. Auf Systemen mit nicht vertrauenswürdigen PCIe-Geräten oder Passthrough in fremde VMs empfahlen die Autoren, den strikten Modus beizubehalten und den Performance-Verlust hinzunehmen.
Zudem stellte sich die Frage, ob Intel- und AMD-Systeme (x86) gleichermaßen profitieren. Hier folgte eine willkommene Dämpfung der Erwartungen: Unter x86 nutzt Linux für die IOMMU meist ohnehin standardmäßig ein verzögertes Bereinigungsverfahren, sodass iommu.strict=0 dort oft keinen Unterschied macht. Ebenso hing die ungewöhnliche 128-Byte-PCIe-Einstellung mit der spezifischen Firmware des GX10 zusammen. Das Team testete zudem reines IOMMU-Passthrough, was gegenüber dem Lazy-Modus auf dem GX10 keinerlei Vorteile brachte, sodass eine noch stärkere Schwächung der Isolation ungerechtfertigt gewesen wäre. Die Bestleistung im Benchmark ist nicht automatisch die beste Sicherheitsrichtlinie für die Produktion.
Das Fazit bleibt bemerkenswert fundiert: Die Tester begannen mit Bootfehlern, unerklärlichen Resets, thermischen Limitierungen und Netzwerkraten, die potente Hardware wie ein Einsteigersystem wirken ließen. Am Ende stand ein Proxmox ARM64 Host, der mit Standard-Kernel und regulären Treibern nahe an das theoretische Limit der Hardware heranreichte. Das Ergebnis zeigt das enorme Potenzial von ARM64 in der Virtualisierung, beweist aber keine pauschale Produktionsreife für jeden Workload. Die wichtigste Lehre lautet: Wenn hochgezüchtete Infrastruktur enttäuscht, besteht der schnellste Weg zur Lösung darin, das Datenblatt beiseitezulegen und den realen Weg jedes einzelnen Datenpakets nachzuverfolgen.
Der Sprung von 6.3 auf 28.1 GB/s war kein Zauberwerk durch neue Hardware. Er resultierte aus der präzisen Lokalisierung von Wartezeiten, dem Beseitigen künstlicher PCIe-Bremsen und der Korrektur fehlerhafter Netzwerkpfade. Wer diesen Test nachvollziehen möchte, sollte diszipliniert vorgehen: Zuerst messen, immer nur einen Parameter auf einmal ändern und sich über die Sicherheitsimplikationen jeder Einstellung im Klaren sein.
In Produktivumgebungen mit mehreren Mandanten oder erhöhten Isolationsanforderungen empfiehlt es sich, die strikte IOMMU-Invalidierung beizubehalten, sofern keine dokumentierte Risikoabwägung den Durchsatzgewinn rechtfertigt.
Häufig gestellte Fragen
Wie schnell lief NVMe/TCP auf dem ASUS GX10 unter Proxmox ARM64?
Blockbridge meldete 6.3 GB/s mit dem Standard-Kernel-Initiator und 28.1 GB/s nach dem Tuning. Die Messungen erfolgten direkt auf dem Host, nicht in einer virtuellen Maschine.
Was bewirkt der Parameter iommu.strict=0?
Er aktiviert verzögerte IOMMU-Invalidierung (sofern unterstützt) und reduziert den Overhead beim DMA-Unmapping. Dies steigert den Durchsatz auf Kosten reduzierter Geräteisolation.
Reichen zwei GX10 Kernel-Parameter allein für 28.1 GB/s aus?
Nein. Der veröffentlichte Test erreichte nach den beiden Parametern zunächst 26.5 GB/s; für die finalen 28.1 GB/s waren zusätzliche Optimierungen an NIC und Warteschlangen erforderlich.