Diagnosing IOMMU Barriers: The Hunt for GPU P2P DMA on a Blackwell System
Introduction
In the course of deploying large language models across multiple NVIDIA RTX PRO 6000 Blackwell GPUs, an invisible but critical bottleneck emerged: the IOMMU (I/O Memory Management Unit) was silently corrupting every GPU-to-GPU data transfer. Message 6242 captures a precise diagnostic moment—a single bash command issued on the Proxmox hypervisor host—where the assistant digs into the IOMMU configuration to answer a direct question from the user: "Is there anything that can be done to get p2p going with iommu? Any bios settings about iommu coverage, related settings?" This seemingly modest command, composed of three piped sub-queries into the Linux kernel's sysfs interface and kernel log, represents a pivotal shift from symptom management (disabling P2P entirely) toward root-cause investigation and potential remediation.
The Context: A System Split by Virtualization
The broader session had been a marathon of ML infrastructure deployment. The assistant had successfully set up an Ubuntu 24.04 environment with eight RTX PRO 6000 Blackwell GPUs, resolved flash-attn build issues, deployed Qwen3.5 models, and navigated the treacherous waters of CUDA 13 upgrades and SGLang patching. But a new challenge emerged when the GPU topology was reconfigured: four GPUs were assigned to an LXC container running SGLang, while the other four were passed through to a SEV-SNP (Secure Encrypted Virtualization with Secure Nested Paging) VM.
The SEV-SNP configuration required amd_iommu=on in full translation mode—not the more permissive iommu=pt (passthrough) mode. This seemingly innocuous kernel parameter had a devastating effect: every GPU-to-GPU P2P DMA transfer produced corrupted data. The assistant had already diagnosed this through a series of tests ([msg 6216] showed every P2P transfer returning MISMATCH), confirmed NCCL worked with NCCL_P2P_DISABLE=1 ([msg 6219]), and deployed a working workaround. But the user, understandably, wanted to know if the root cause could be fixed rather than just worked around.
The Message: A Three-Pronged Diagnostic Probe
The subject message (msg id=6242) is a single tool call—a bash command executed on the Proxmox host at 10.1.2.6:
ssh root@10.1.2.6 'dmesg | grep -iE "iommu|AMD.Vi" | grep -v PAGE_FAULT | head -20; echo "---"; cat /sys/class/iommu/ivhd*/amd-iommu/features 2>/dev/null; echo "---"; for dev in 0000:01:00.0 0000:11:00.0 0000:61:00.0 0000:71:00.0; do echo -n "$dev iommu_group="; basename $(readlink -f /sys/bus/pci/devices/$dev/iommu_group); drv=$(readlink -f /sys/bus/pci/devices/$dev/iommu_group/type 2>/dev/null); cat /sys/bus/pci/devices/$dev/iommu_group/type 2>/dev/null; done'
The command is structured in three distinct segments, separated by echo "---" markers:
Segment 1: Filtering the Kernel Log for Non-Fault IOMMU Events The first pipeline searches dmesg for lines containing "iommu" or "AMD.Vi" (case-insensitive), then excludes any line containing "PAGE_FAULT". The intent is clear: the assistant already knew from earlier diagnostics that the IOMMU was generating page faults during P2P transfers ([msg 6241] showed dozens of IO_PAGE_FAULT entries). By filtering those out, the assistant hoped to find other IOMMU-related messages—perhaps configuration announcements, device assignment details, or feature flags logged at boot time—that could shed light on the IOMMU's operating mode.
Segment 2: Reading IOMMU Hardware Features The second probe reads from a sysfs path: /sys/class/iommu/ivhd*/amd-iommu/features. This is a deeply kernel-internal interface. The ivhd* wildcard matches AMD IOMMU hardware device instances (IVHD = I/O Virtualization Hardware Descriptor, a term from the ACPI IVRS table). The features file exposes the IOMMU's capability flags as a bitmask. Understanding this requires knowledge that AMD's IOMMU implementation exposes its IVRS (I/O Virtualization Reporting Structure) table checksum and feature flags through sysfs—information normally only seen by firmware developers and kernel engineers.
Segment 3: Mapping GPU PCIe Devices to IOMMU Groups The third probe iterates over four specific PCIe addresses (0000:01:00.0, 0000:11:00.0, 0000:61:00.0, 0000:71:00.0)—these are the four NVIDIA GPUs on the system. For each, it resolves the IOMMU group number by following the iommu_group symlink under the device's sysfs node, then reads the group's type file. The IOMMU group is a kernel construct that determines which devices share an IOMMU translation domain. Devices in the same group can potentially DMA to each other under certain conditions; devices in different groups are isolated.
Interpreting the Results
The output reveals three critical pieces of information:
---
a5bf732fa2295afe:53f
a5bf732fa2295afe:53f
a5bf732fa2295afe:53f
a5bf732fa2295afe:53f
a5bf732fa2295afe:53f
a5bf732fa2295afe:53f
a5bf732fa2295afe:53f
a5bf732fa2295afe:53f
---
0000:01:00.0 iommu_group=42
DMA-FQ
0000:11:00.0 iommu_group=61
DMA-FQ
0000:61:00.0 iommu_group=28
DMA-FQ
0000:71:00.0 iommu_group=10
DMA-FQ
First segment: silence. The grep -v PAGE_FAULT filter eliminated all IOMMU messages, confirming that every IOMMU-related kernel log entry was a page fault. There were no boot-time configuration announcements, no feature flag dumps, no device assignment logs. This is itself informative—it means the kernel isn't logging IOMMU initialization details at the default log level, or the boot messages have been rotated out of the dmesg buffer.
Second segment: the features string. The value a5bf732fa2295afe:53f appears eight times (one per IOMMU instance). The portion before the colon is the IVRS table checksum, used by the kernel to verify the ACPI table integrity. The 53f after the colon is the feature bitmask. In AMD's IOMMU specification, bit flags indicate capabilities like PPR (Peripheral Page Request) support, GA (Guest Address) translation, HT (HyperTransport) tunneled commands, and more. The presence of this value confirms the IOMMU is operational and has been initialized by the kernel.
Third segment: IOMMU group isolation. Each GPU is in a different IOMMU group (42, 61, 28, 10), and all groups are of type DMA-FQ—DMA with Function Queuing. This is the standard IOMMU translation mode (as opposed to DMA-PT for passthrough or DMA-API for kernel-managed). The fact that each GPU has its own IOMMU group is the critical finding: under full IOMMU translation with separate groups, the IOMMU only maps system memory addresses into each device's domain. When GPU A tries to DMA directly to GPU B's PCIe BAR (Base Address Register) memory, the IOMMU has no translation entry for that address, resulting in an IO_PAGE_FAULT. The separate groups mean there is no "coherent domain" that spans multiple GPUs.
Why This Matters: The P2P DMA Problem
The IOMMU group isolation is the fundamental barrier. For GPU-to-GPU P2P DMA to work through an IOMMU in full translation mode, either:
- All GPUs must be in the same IOMMU group (sharing a translation domain), or
- The IOMMU must be configured in passthrough mode (
iommu=pt), which bypasses translation for assigned devices, or - The system must support a feature like PCIe ACS (Access Control Services) override or ARI (Alternative Routing-ID Interpretation) that can create peer-to-peer windows through the IOMMU. The assistant's diagnostic confirms that option 1 is not the case—the GPUs are deliberately isolated into separate groups by the kernel based on the PCIe topology and the IVRS table from the BIOS. Option 2 is unavailable because the SEV-SNP VM configuration requires full IOMMU translation for secure memory encryption. Option 3 depends on BIOS settings that may or may not be exposed on this platform.
Knowledge Required and Knowledge Produced
Input knowledge required to craft this command includes: familiarity with the Linux sysfs interface for PCIe devices, understanding of IOMMU concepts (groups, translation domains, DMA-FQ vs DMA-PT), knowledge of AMD's IOMMU implementation (IVRS tables, feature bitmasks), awareness of how GPU P2P DMA works at the hardware level (peer-to-peer BAR access), and the specific PCIe topology of this system (knowing which addresses correspond to GPUs).
Output knowledge produced includes: confirmation that no non-fault IOMMU events exist in the kernel log, the IVRS checksum and feature bitmask for the AMD IOMMU, and the definitive mapping of each GPU to its own DMA-FQ IOMMU group. This information is immediately actionable: it tells the assistant and user that BIOS-level IOMMU group reconfiguration or ACS override would be needed to enable P2P, and that no software workaround within the current IOMMU configuration is possible.
Assumptions and Limitations
The assistant makes several assumptions in this diagnostic. It assumes that the sysfs paths are stable and accessible (they are, on this kernel version). It assumes that the four PCIe addresses correspond to the four GPUs assigned to the LXC container (this was established earlier in the session). It assumes that the IOMMU features file contains meaningful data (it does, but interpreting the 53f bitmask requires the AMD IOMMU specification).
A notable limitation is that the grep -v PAGE_FAULT filter may be too aggressive—if there were IOMMU messages containing the substring "PAGE_FAULT" in a different context (e.g., "PAGE_FAULT count: 0"), they would also be excluded. However, in practice, the IOMMU page fault messages all follow the format IO_PAGE_FAULT domain=... address=... flags=..., so the filter is safe.
Another limitation: the command doesn't check the kernel's IOMMU command-line parameters or the IVRS table directly. The amd_iommu=on parameter is known from earlier diagnostics ([msg 6239] showed the kernel cmdline), but the command doesn't verify whether iommu=pt could be enabled per-device or whether the BIOS exposes ACS control. These would be natural next steps.
The Broader Narrative
This message sits at an inflection point in the session. The assistant had been operating in "fix it" mode—identifying the P2P corruption, disabling it, and moving on to benchmarking. But the user's question forces a deeper investigation: can the root cause be addressed? The assistant's response is not just a command but a methodology—it systematically probes the IOMMU configuration at three levels (kernel log, hardware features, device topology) to build a complete picture.
The results are ultimately negative for the user's hopes: the GPUs are irrevocably isolated by the IOMMU under the current configuration. But this negative result is valuable—it prevents wasted effort trying software workarounds and clarifies that the path to P2P lies in BIOS configuration (ACS override, IOMMU coverage settings) or hardware topology changes. The assistant has transformed an abstract question about BIOS settings into a concrete diagnostic with clear next steps.
Conclusion
Message 6242 exemplifies the kind of deep systems debugging that characterizes modern ML infrastructure work. A single bash command, carefully constructed from three probes into kernel internals, extracts a wealth of information about the IOMMU configuration. It demonstrates that understanding GPU performance in virtualized environments requires knowledge spanning from ACPI firmware tables to CUDA runtime behavior. While the answer to the user's question—"can P2P work?"—appears to be "not under this configuration," the diagnostic itself is a model of systematic troubleshooting: isolate the symptom, probe the mechanism, confirm the root cause, and only then evaluate remediation options. The IOMMU group isolation revealed here becomes the foundation for all subsequent decisions about P2P DMA on this system.