The Last Hope for P2P: Diagnosing NVIDIA's DmaRemapPeerMmio on Blackwell

In the high-stakes world of multi-GPU inference serving, every microsecond counts. When eight NVIDIA RTX PRO 6000 Blackwell GPUs are split across two NUMA domains — four for the nvidia driver running SGLang and four for a SEV-SNP protected VM via VFIO — the IOMMU must remain in full translation mode. But this comes at a cost: GPU peer-to-peer (P2P) DMA, the direct GPU-to-GPU data transfer path that bypasses host memory, is broken under IOMMU translation. The system falls back to NCCL's SHM transport, which routes P2P traffic through host memory, adding latency and reducing throughput.

Message [msg 6330] captures a pivotal moment in the assistant's months-long quest to restore P2P DMA on this Blackwell-based system. After discovering that the IOMMU identity domain approach — the most promising path to P2P restoration — was fundamentally incompatible with Blackwell GPUs (the Firmware Security Processor, or FSP, crashes with error 0x177 when IOMMU is in identity mode), the assistant pivots to its last remaining option: testing whether NVIDIA's own DmaRemapPeerMmio=1 driver parameter can solve the problem from within the driver itself.

The Message: A Focused Diagnostic

The message itself is deceptively simple:

Let me write a focused P2P transfer test that also checks if the data is correct, and explicitly tests with P2P enabled. I want to test the current state (DmaRemapPeerMmio=1 with DMA-FQ): [write] /home/theuser/glm-kimi-sm120-rtx6000bw/p2p_test.py Wrote file successfully.

The assistant writes a new Python script, p2p_test.py, to the project directory. This is a deliberate act of creating a focused diagnostic tool, rather than reusing the existing gpu_diag.py which had a broader scope. The LSP errors about unresolved torch imports that follow are irrelevant noise — they come from the host machine's language server, which doesn't have PyTorch installed, while the actual execution will happen inside the container environment where PyTorch is available.

The Reasoning and Motivation

To understand why this message was written, we must trace the assistant's reasoning through the preceding messages. The journey began in [msg 6319] when the assistant first attempted to set IOMMU identity domains for the NUMA0 GPU groups. The idea was elegant: keep IOMMU in full translation mode globally (required for SEV-SNP), but selectively set individual IOMMU groups to "identity" mode for the four nvidia-bound GPUs. This would give those GPUs direct DMA access to each other's BAR regions while preserving translation for the VFIO devices.

The initial test was promising — the identity domains were set successfully. But then disaster struck: after rebooting, the Blackwell FSP failed to initialize with error 0x177. The FSP, a dedicated security processor embedded in Blackwell GPUs, requires specific DMA mappings set up by the kernel's DMA API during its boot sequence. Identity mode bypasses this DMA API, starving the FSP of the mappings it needs. No software-level reset — not FLR (Function Level Reset), not SBR (Secondary Bus Reset), not even CXL bus reset — could clear this state once set. The approach was definitively blocked.

After reverting to the working DMA-FQ configuration in [msg 6324], the assistant pivoted to a completely different strategy in [msg 6326]: examining the nvidia driver's own parameters for P2P support under IOMMU. The cat /proc/driver/nvidia/params output revealed a critical parameter: DmaRemapPeerMmio: 1. This parameter controls whether the nvidia driver maps peer GPU MMIO (BAR) regions through the IOMMU DMA remapping infrastructure. If it works correctly, it would solve the P2P problem entirely within the driver, without any IOMMU group manipulation.

Assumptions and Knowledge Required

To understand this message, one needs substantial background knowledge spanning multiple domains:

GPU Architecture: Blackwell GPUs have a Firmware Security Processor (FSP) that handles secure boot and initialization. The FSP runs its own firmware and requires specific DMA mappings from the kernel during its boot sequence. This is a Blackwell-specific feature not present in earlier architectures like Hopper or Ada.

IOMMU Internals: The AMD IOMMU (used on this AMD EPYC platform) supports per-group domain types: DMA-FQ (full translation with flush queue for performance) and identity (passthrough, no translation). The DMA-FQ type is the default and provides full IOMMU translation with optimized TLB flushing. The identity type bypasses translation entirely, allowing direct physical address access.

NVIDIA Driver Architecture: The nvidia kernel module (nvidia.ko) has a parameter DmaRemapPeerMmio that controls peer GPU BAR mapping. When enabled, the driver calls dma_map_resource() to create IOMMU mappings for other GPUs' BAR regions, enabling P2P access even under full IOMMU translation. This is distinct from the CUDA-level P2P access control (cudaDeviceEnablePeerAccess).

PCIe Topology: The four NUMA0 GPUs are at addresses 01:00.0, 11:00.0, 61:00.0, and 71:00.0, each behind its own PCIe root port. The bridges at 00:01.1, 10:01.1, 60:01.1, and 70:01.1 control secondary bus resets for each GPU.

The SEV-SNP Constraint: Secure Encrypted Virtualization with Secure Nested Paging (SEV-SNP) requires the AMD IOMMU to be in full translation mode (amd_iommu=on). This is a hard requirement that cannot be relaxed, which is why the global iommu.passthrough=1 kernel parameter is not an option.

What the Message Creates

The output of this message is a new diagnostic file, p2p_test.py. While we don't see its full contents in the message itself, subsequent messages reveal its design. In [msg 6332], the test is executed on the container:

GPUs: 4
NCCL_P2P_DISABLE: not set

=== P2P Access Capability ===
  GPU 0 -> GPU 1: canAccessPeer=True
  GPU 0 -> GPU 2: canAccessPeer=True
  GPU 0 -> GPU 3: canAccessPeer=True
  ...
=== P2P Transfer Tests ===
  GPU 0 -> GPU 1: OK (data correct)
  GPU 0 -> GPU 2: FAILED (data mismatch)
  GPU 0 -> GPU 3: FAILED (data mismatch)
  GPU 1 -> GPU 0: OK (data correct)
  ...

The test reveals a fascinating pattern: DmaRemapPeerMmio=1 is partially working. Some peer pairs transfer correctly while others produce data corruption. Specifically, transfers FROM GPU 0 (at 01:00.0) TO any other GPU fail, while transfers FROM higher-numbered GPUs TO lower-numbered ones succeed. This directional asymmetry points to an incomplete IOMMU mapping — the nvidia driver is remapping some peer BARs but not all, likely due to a bug in the mapping order or a missing mapping for certain BAR address ranges.

The dmesg output in [msg 6333] confirms IO_PAGE_FAULTs from GPUs 61:00.0 and 71:00.0 trying to access peer BAR addresses, with faulting addresses like 0x6e000010000 falling into GPU BAR space.

Mistakes and Incorrect Assumptions

The message itself doesn't contain explicit mistakes — it's a well-reasoned diagnostic step. However, the broader context reveals an implicit assumption that turned out to be incorrect: the assistant assumed that DmaRemapPeerMmio=1 would either work fully or not at all. The reality was a frustrating middle ground where some pairs worked and others didn't, with a directional pattern suggesting a driver bug rather than a fundamental architectural limitation.

There's also an implicit assumption that the LSP errors about unresolved imports are meaningful. They are not — the torch package is installed inside the container environment, not on the host where the LSP runs. The assistant correctly ignores these errors, but a less experienced operator might be misled into thinking the script is broken.

The Thinking Process

The assistant's thinking is visible in the message's structure and phrasing. The phrase "focused P2P transfer test that also checks if the data is correct" reveals a key insight: the existing gpu_diag.py only checked canDeviceAccessPeer (a capability flag) and attempted transfers, but didn't validate data integrity. A P2P transfer that silently corrupts data is worse than no P2P at all. The new test explicitly checks data correctness, raising the bar from "does it work?" to "does it work correctly?"

The phrase "I want to test the current state (DmaRemapPeerMmio=1 with DMA-FQ)" shows the assistant's systematic approach. Rather than trying yet another configuration change, it's stepping back to gather data about the current working state. This is a classic debugging pattern: before changing anything, understand exactly what the current behavior is.

The decision to write a new file rather than modify gpu_diag.py is also telling. It preserves the existing diagnostic tool while creating a purpose-built instrument for the specific question at hand. This is good engineering hygiene — each tool has a clear responsibility, and modifications to existing tools don't risk breaking other diagnostic capabilities.

The Broader Significance

Message [msg 6330] represents a strategic inflection point in the session. The IOMMU identity domain approach was elegant but blocked by hardware. The DmaRemapPeerMmio approach is messier — it's a driver-level workaround that the assistant doesn't control — but it's the only remaining path to P2P restoration. The test results that follow in [msg 6332] and [msg 6333] will determine whether this path is viable or whether the assistant must accept the performance penalty of NCCL_P2P_DISABLE.

In the end, the partial success of DmaRemapPeerMmio=1 — some pairs work, others don't — is perhaps the most frustrating outcome possible. A clean pass would have restored P2P. A clean failure would have closed the door decisively. Instead, the assistant is left with a tantalizing but broken capability, a driver bug report waiting to be filed, and the pragmatic decision to continue with NCCL_P2P_DISABLE=1 and focus on the MTP speculation optimization that is already delivering 12-45% throughput improvement.

The message is a masterclass in systematic debugging: formulate a hypothesis, design a targeted test, execute it, and let the data guide the next decision. It's also a reminder that in systems engineering, the most elegant solutions often fail against hardware reality, and the grubbiest driver parameters are sometimes the last line of defense.