The Architecture of Impossibility: A Deep Dive into GPU P2P DMA Across Eight Blackwell GPUs in a Proxmox VM

Introduction

In the world of high-performance machine learning inference, the difference between a working deployment and a production-ready one often comes down to a single number: the latency of inter-GPU communication. For tensor-parallel inference across multiple GPUs, every all-reduce operation—and there are hundreds per inference step—depends on the ability of GPUs to exchange data with minimal overhead. When that overhead doubles, throughput collapses. When it doubles in a virtualized environment, the cause is rarely a simple configuration mistake. More often, it is a fundamental architectural constraint buried deep in the hardware topology, invisible to all but the most determined investigator.

This article synthesizes a remarkable debugging session spanning dozens of conversation rounds, in which a user and an AI assistant systematically peeled back layer after layer of abstraction in pursuit of a single goal: enabling Peer-to-Peer (P2P) DMA between eight NVIDIA RTX PRO 6000 Blackwell GPUs running inside a Proxmox KVM virtual machine. The journey took them from GRUB configuration files to AMD EPYC PCIe root complex topology, from IOMMU groups to Access Control Services, from sysfs NUMA affinity hacks to NCCL topology XML workarounds. What they discovered was not a fix, but a profound understanding of why no fix exists—and a set of pragmatic compromises that make the best of an impossible situation.

The Hardware: A Server Designed for Bandwidth, Not Sharing

The physical machine at the center of this story is an ASUS ESC8000A-E13 server motherboard, populated with dual AMD EPYC 9335 processors and eight NVIDIA RTX PRO 6000 Blackwell GPUs, each equipped with 96GB of VRAM. On paper, this is a dream configuration for large model inference: nearly a terabyte of aggregate GPU memory, PCIe Gen5 x16 connectivity to every slot, and the massive compute throughput of Blackwell architecture.

But the ASUS ESC8000A-E13 has a critical design characteristic that would become the central obstacle of this entire investigation: each GPU occupies its own dedicated PCIe root complex. There is no shared PCIe switch between any pair of GPUs. On the AMD EPYC platform, each socket exposes multiple root complexes via the Data Fabric (Infinity Fabric), and the motherboard's slot layout maps each physical x16 slot to its own root port. This design maximizes per-GPU bandwidth—every card gets a direct, uncontested Gen5 x16 link to the CPU—but it completely eliminates the possibility of direct GPU-to-GPU communication through the PCIe fabric.

In bare-metal Linux, this topology is manageable. GPUs on the same socket can communicate through the Data Fabric's internal routing, and nvidia-smi topo -m reports NODE connections for intra-socket pairs and SYS for cross-socket pairs. But in a virtualized environment, this topology becomes a wall. The VFIO (Virtual Function I/O) driver, which mediates device passthrough in KVM, assigns each GPU to its own IOMMU group based on the physical PCIe hierarchy. Devices in different IOMMU groups cannot perform direct DMA to each other—a security guarantee baked into the virtualization architecture. And since each GPU is on its own root complex, they land in separate groups, and no amount of software configuration can merge them.

The BAR Allocation Crisis: A Necessary Prerequisite

Before the team could even begin to address P2P, they had to solve a more immediate crisis. The VM, originally configured with the legacy i440FX chipset, had been migrated to the modern Q35 chipset with proper PCIe passthrough (pcie=1). This migration was necessary for any hope of P2P—the i440FX flat bus could never support direct GPU-to-GPU communication. But the migration triggered a catastrophic failure: only 2 of the 8 GPUs were detected after reboot.

The culprit was a BAR (Base Address Register) allocation failure. Each RTX PRO 6000 GPU requires a 128GB BAR2 region to map its VRAM into the system's physical address space. With eight GPUs, that's 1TB of contiguous 64-bit MMIO space needed just for VRAM. The SeaBIOS firmware used by the VM could not allocate this space, leaving 6 GPUs with the ominous error BAR2 is 0M @ 0x0.

The fix, suggested by the guest kernel itself in its dmesg output, was the pci=realloc kernel parameter. This tells the Linux PCI subsystem to discard the firmware's failed BAR assignments and perform its own allocation pass during boot. The implementation, however, was anything but straightforward.

The Cloud-Init Gotcha: When a Fix Silently Fails

The assistant's first attempt to add pci=realloc followed the standard Ubuntu procedure: edit /etc/default/grub, run update-grub, reboot. But after reboot, the kernel command line showed no trace of the parameter. Only 2 GPUs remained visible.

The clue was hidden in the update-grub output, which showed two sourcing events:

Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/50-cloudimg-settings.cfg'

The cloud-init configuration file, generated by the Ubuntu cloud image build process, was setting GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0" after the main GRUB file was sourced. Because GRUB's configuration system sources grub.d/ files in lexicographic order after the main file, the cloud-init override silently clobbered the assistant's carefully added pci=realloc parameter.

This is a classic example of what makes infrastructure debugging so challenging: the system's behavior is determined not by any single configuration file, but by the ordering of multiple files in a chain. The fix was to modify the cloud-init file directly, appending pci=realloc to its existing console parameters. After a second reboot and a tense period of network unavailability, all 8 GPUs came online with their full 96GB VRAM.

The Moment of Truth: Eight GPUs Online, P2P Still Dead

With all 8 GPUs detected and operational, the team ran the critical diagnostic: nvidia-smi topo -p2p r. The result was an 8×8 matrix where every off-diagonal cell read "NS" (Not Supported). The companion command nvidia-smi topo -m showed all connections as "PHB" (PCIe Host Bridge)—the weakest possible topology classification, indicating that each GPU is behind its own host bridge with no shared PCIe switch.

The dmesg output confirmed that pci=realloc was active and that no BAR assignment errors remained. The PCIe subsystem was clean. But the NVIDIA driver's topology assessment was unambiguous: direct GPU-to-GPU DMA was not possible.

This was the moment the investigation pivoted from "how do we fix this configuration" to "what is the fundamental constraint?" The assistant's initial instinct was to proceed to benchmarking—to measure whether the Q35 migration alone had improved throughput even without P2P. But the user intervened with a sharp redirection: "no bench, first can we fix p2p properly?" This single message (see [14]) reframed the entire session. The team would not accept a degraded baseline; they would confront the hardest problem first.

The ACS Experiment: A Well-Known Hack That Didn't Help

The next logical step was to investigate Access Control Services (ACS), a PCIe capability that enforces isolation between downstream devices. In many virtualized environments, ACS is the mechanism that keeps devices in separate IOMMU groups. Disabling ACS in the BIOS has been known to merge IOMMU groups, potentially enabling P2P.

The user entered the BIOS and disabled ACS. The system rebooted. The assistant had prepared a comprehensive validation playbook (see [60]) covering IOMMU groups, IOMMU passthrough mode, PCIe link speeds, power management settings, and the ultimate P2P test inside the VM.

The results were sobering. The ACS disable successfully renumbered the IOMMU groups, but it critically failed to merge them. Each GPU remained in its own separate group. The assistant's analysis ([61], [62]) explained why: ACS only controls forwarding on PCIe bridges and switches that have multiple downstream devices. Since each GPU is on its own dedicated root complex—with no shared bridge between any pair—ACS has nothing to control. The isolation is baked into the hardware topology at a deeper level than ACS can reach.

This was the turning point. The assistant concluded with brutal honesty: "P2P (direct GPU-to-GPU DMA) cannot be enabled in this VM setup." The hardware topology—one GPU per root complex—is a fundamental constraint that no software configuration can overcome.

The NUMA Topology Investigation: A Different Kind of Problem

Even without P2P, the team recognized a second-order problem: the VM was not exposing proper NUMA topology to the GPUs. On bare metal, GPUs 0–3 are on NUMA node 0 and GPUs 4–7 on NUMA node 1, with NODE interconnects within each group and SYS across groups. In the VM, all eight GPUs showed PHB with no NUMA distinction. This meant NCCL (the NVIDIA Collective Communications Library) could not differentiate between intra-socket and cross-socket communication paths, potentially causing suboptimal algorithm selection.

The assistant embarked on a detailed mapping exercise, correlating the Proxmox PCI resource mapping to physical GPU PCI addresses and host NUMA nodes ([34], [35]). The discovery was fortuitous: the two Q35 PCIe root port groups (00:10.x for hostpci0–3 and 00:1c.x for hostpci4–7) happened to align with the physical NUMA domains. VM GPUs 0–3 mapped to physical NUMA 1, and VM GPUs 4–7 mapped to physical NUMA 0. The hardware grouping was correct, but the VM was not exposing this grouping as NUMA affinity.

The assistant explored several approaches to fix this. The most ambitious was using QEMU's pxb-pcie expander bus device with explicit NUMA node assignments, which would create virtual PCIe switches that mirror the physical topology ([25]). This approach, however, conflicted with Proxmox's automatic hostpci device management and would require removing the standard configuration in favor of raw QEMU arguments—a risky operation on a production VM.

A simpler but ultimately futile approach was writing directly to the sysfs numa_node attribute of each GPU's PCI device ([44]). The assistant assigned GPUs 0–3 to numa_node=1 and GPUs 4–7 to numa_node=0, and the kernel accepted the writes. But when the verification came in [45], nvidia-smi topo -m showed no change. The NVIDIA driver builds its topology from the actual PCIe hierarchy, not from the kernel's NUMA affinity hints. The sysfs writes changed where the kernel thinks the devices live for memory allocation, but they did not change the PCIe topology that the NVIDIA driver sees.

The Pragmatic Pivot: NCCL Topology XML

With the hardware-level approaches exhausted, the assistant pivoted to a software-level workaround: an NCCL topology XML file ([40], [41], [42]). NCCL supports loading a custom topology description via the NCCL_TOPO_FILE environment variable, which overrides its auto-detected topology. The assistant created a file at ~/nccl_topo.xml that described the true physical layout:

The BIOS Question: A Final Frontier

At this point, the user asked a question that opened a new front: "Btw any settings in bios that are highly warrated to set? Asus E13 GPU server." ([49]) This question recognized that the software-level workarounds might only be part of the solution, and that the foundation of performance lies in the host firmware configuration.

The assistant launched parallel web searches ([50]), targeting both the specific ASUS platform and general AMD EPYC BIOS guidance. The search queries covered NPS (NUMA Per Socket), IOMMU configuration, ACS (Access Control Services), Above 4G Decoding, SR-IOV, PCIe Relaxed Ordering, and Resizable BAR—all settings that could impact multi-GPU inference performance. The searches converged on the AMD Instinct Customer Acceptance Guide's BIOS Settings page, an authoritative source for EPYC platform configuration.

This investigation, while not producing immediate changes, validated the user's intuition that BIOS configuration matters and provided a documented baseline for future optimization.

The Desperate Turn: "Hacky/Insecure Ways"

After the ACS experiment failed and the hardware topology was confirmed as the fundamental barrier, the user asked a question that crystallized the entire session's trajectory: "Are there hacky/insecure ways to get SYS/NODE in kvm?" ([65])

This eight-word question is remarkable for what it reveals. The user has fully absorbed the assistant's explanation of the hardware topology constraint. They understand that proper configuration cannot solve this problem. They are willing to sacrifice security guarantees for performance. And they know exactly what they're looking for: SYS and NODE are the topology types reported by nvidia-smi topo -m, representing the ideal NUMA-aware connectivity that NCCL needs for optimal algorithm selection.

The assistant responded by researching VFIO kernel parameters like vfio_iommu_type1.allow_unsafe_interrupts, investigating whether IOMMUFD (a newer VFIO backend) handles P2P differently, and exploring NVIDIA's nv_peer_mem module ([66]). This research represented the final frontier of the investigation—the point at which the team was willing to explore the system's darkest corners, trading security for performance.

The Empty Message: A Pause for Consolidation

In the midst of this research, the user sent an empty message ([67]). No text, no command, no question—just a blank space between two substantial contributions from the assistant. In the context of a long and intense debugging session, this silence carried meaning. It signaled readiness, a pause for processing, or simply the absence of new information.

The assistant interpreted this empty message as a checkpoint and responded with a comprehensive conversation_data summary—a structured document capturing every discovery, every configuration change, every benchmark result, and every unresolved issue from the entire session. This summary became a permanent record of the session's state, invaluable for anyone returning to the work later.

What Was Learned: The Architecture of Impossibility

The central finding of this investigation is that the hardware topology of the ASUS ESC8000A-E13 motherboard—one GPU per dedicated PCIe root complex—fundamentally prevents P2P DMA in a KVM virtualized environment. This is not a configuration problem, not a BIOS setting, not a kernel parameter that can be tuned. It is a physical design constraint.

The mechanism works as follows:

  1. The AMD EPYC platform exposes multiple PCIe root complexes, each connected to the CPU's Data Fabric.
  2. The ASUS motherboard routes each GPU slot to its own root complex, maximizing per-GPU bandwidth.
  3. In KVM with VFIO passthrough, each root complex becomes a separate IOMMU group.
  4. VFIO enforces DMA isolation between IOMMU groups as a security guarantee.
  5. No software configuration—not ACS disable, not kernel parameters, not sysfs hacks—can override this isolation when the GPUs are on separate root complexes. The practical consequence is a ~13µs latency floor for all inter-GPU communication in the VM, compared to ~5–8µs on bare metal. This doubling of latency is catastrophic for the all-reduce operations that underpin tensor-parallel inference.

The Pragmatic Path Forward

Despite the impossibility of true P2P DMA, the team established a set of pragmatic workarounds:

  1. NCCL topology XML: A software-level hint that tells NCCL the correct NUMA topology, enabling better algorithm selection even without hardware P2P.
  2. NUMA-aware VM configuration: Ensuring the VM's CPU and memory topology matches the physical NUMA layout, minimizing cross-socket traffic.
  3. TP4+PP2 parallelism: Using a hybrid of tensor parallelism (within NUMA domains) and pipeline parallelism (across domains) to minimize cross-socket communication.
  4. BIOS optimization: Configuring NPS mode, IOMMU settings, and power management for optimal GPU performance. These workarounds do not eliminate the virtualization overhead, but they make the best of a constrained situation. For the user's GLM-5-NVFP4 inference workload, the path to 1,000+ tokens per second likely requires either accepting the ~13µs latency floor or moving to bare metal.

Conclusion

This debugging session is a masterclass in systematic investigation at the hardware-software boundary. The team moved from GRUB configuration to PCIe topology, from IOMMU groups to ACS settings, from sysfs hacks to NCCL XML files, testing hypotheses and falsifying them with clean, unambiguous evidence. Each layer peeled back revealed another constraint, until the fundamental hardware topology stood bare.

The lesson is both sobering and empowering: some problems cannot be solved with software. The ASUS ESC8000A-E13's one-GPU-per-root-complex design is a deliberate engineering choice that optimizes for bandwidth at the expense of P2P capability. In a virtualized environment, this choice creates an insurmountable barrier. But understanding why the barrier exists—tracing it from the physical PCIe layout through the IOMMU groups to the VFIO driver's isolation guarantees—is itself a form of progress. It transforms a frustrating mystery into a documented constraint, and it enables informed decisions about whether to accept the limitation, work around it, or change the hardware.

For anyone deploying multi-GPU inference in virtualized environments, this investigation provides a roadmap: check your PCIe topology first, understand your IOMMU groups, and accept that some hardware designs are fundamentally incompatible with virtualized P2P DMA. The architecture of impossibility is, paradoxically, a form of knowledge that enables progress.## References

[1] "The Moment of Truth: When a Kernel Fix Fails to Materialize" — Analysis of the failed pci=realloc verification at msg 351.

[2] "The Cloud-Init Gotcha: How a Single GRUB Override Derailed an 8-GPU Debugging Session" — Discovery of the cloud-init GRUB override at msg 352.

[3] "The Cloud-Init Override: A Lesson in Ubuntu Boot Configuration" — Detailed analysis of the GRUB configuration chain at msg 353.

[4] "The Critical Reboot: Applying pci=realloc to Rescue Eight GPUs in a Proxmox VM" — The fix application at msg 354.

[5] "The Moment of Verification: A Failed SSH Connection in a GPU Passthrough Debugging Session" — The tense verification wait at msg 355.

[6] "The Silence After the Reboot: A Diagnostic Check That Reveals Uncertainty" — Post-reboot diagnostic at msg 356.

[7] "The Waiting Game: A 60-Second Sleep That Bridged Failure and Breakthrough" — The waiting period at msg 357.

[8] "The Five Words That Carried a Terabyte of Context" — User confirmation at msg 358.

[9] "Verifying the pci=realloc Fix for 8-GPU Passthrough" — Verification at msg 359.

[10] "The Bittersweet Victory: Eight GPUs Online, But P2P Remains Elusive" — The milestone at msg 360 where all 8 GPUs are detected but P2P is still NS.

[11] "The P2P Barrier: A Pivotal Diagnostic Moment in Multi-GPU Virtualization" — P2P diagnostic at msg 361.

[12] "The Moment of Breakthrough: All 8 GPUs Come Online" — Breakthrough at msg 362.

[13] "The Empty Bash Command: A Pivot Point in Human-AI Priority Alignment" — Empty command at msg 363.

[14] "\"No Bench, First Can We Fix P2P Properly?\"" — The user's redirection at msg 364.

[15] "The P2P Pivot: A Critical Juncture in GPU Virtualization Debugging" — The pivot to P2P research at msg 365.

[16] "The Research Pivot: When Virtualization Meets Hardware Reality in GPU P2P DMA" — Research phase at msg 366.

[17] "The PCIe Topology Ceiling: Confronting the Limits of GPU Peer-to-Peer DMA in Virtualized Environments" — Topology analysis at msg 367.

[18] "The Moment of Truth: Diagnosing P2P Performance After a VM Migration" — P2P benchmark at msg 368.

[19] "The Honest Assessment: Why P2P GPU DMA Cannot Be Enabled in a Virtualized Environment" — The honest assessment at msg 369.

[20] "The Topology Question: When a User Asks \"Is This Better or Worse?\"" — User's topology comparison at msg 370.

[21] "The Topology That Wasn't: How a Single Comparison Revealed the Hidden Cost of GPU Virtualization" — Topology analysis at msg 371.

[22] "The NUMA Revelation: A Pivotal Data Point in the Quest for GPU P2P in a Proxmox VM" — NUMA discovery at msg 372.

[23] "Mapping the Invisible Topology: Tracing GPU NUMA Affinity Across the Virtualization Boundary" — NUMA mapping at msg 373.

[24] "Mapping the Virtual PCIe Topology: A Diagnostic Pivot in the Quest for GPU P2P in Proxmox" — Virtual topology mapping at msg 374.

[25] "The Virtual Topology Mirage: Chasing PCIe P2P in a Proxmox VM with 8 Blackwell GPUs" — Virtual PCIe switch proposal at msg 375.

[26] "The Missing Mapping File: A Pivotal Moment in the P2P Debugging Journey" — Missing config file at msg 376.

[27] "The Moment the Bridge Broke: A Failed SSH Hop and the Limits of Remote Debugging" — Failed SSH at msg 377.

[28] "The Silence That Speaks: Analyzing an Empty Message in a P2P DMA Debugging Session" — Empty message at msg 378.

[29] "The Empty File That Speaks Volumes: A Pivotal Information-Gathering Moment in GPU P2P Debugging" — Empty file at msg 379.

[30] "The Missing Config: Debugging PCI Mapping in a Proxmox GPU VM" — Missing mapping config at msg 380.

[31] "The Mapping That Wasn't a Directory: Uncovering Proxmox PCI Passthrough Configuration" — Mapping directory at msg 381.

[32] "The Pivot Point: A Single Command That Unlocked the GPU Topology Puzzle" — Topology pivot at msg 382.

[33] "Decoding the Proxmox PCI Mapping: The Moment of Truth" — PCI mapping decoded at msg 383.

[34] "The Topology Revelation: Mapping Physical NUMA to Virtual GPUs" — NUMA-to-virtual mapping at msg 384.

[35] "The Diagnostic Pivot: How a Single NUMA Check Shaped the GPU Topology Fix Strategy" — NUMA diagnostic pivot at msg 385.

[36] "The PCIe Topology Tango: Wrestling NUMA Affinity into a Proxmox VM" — NUMA affinity approaches at msg 386.

[37] "The Quiet Verification: How a Single dmesg Grep Anchored a GPU P2P Investigation" — dmesg verification at msg 387.

[38] "The Pragmatic Pivot: Choosing Software Topology Over Hardware Perfection" — Pragmatic pivot at msg 388.

[39] "The Gen1 Revelation: A Single Diagnostic Command That Exposed Virtualization Overhead" — Gen1 link speed discovery at msg 389.

[40] "The Pragmatic Topology: How an NCCL XML File Became the Solution" — NCCL topology XML creation at msg 390.

[41] "The NCCL Topology XML Pivot: A Software Workaround for a Hardware Impossibility" — NCCL XML pivot at msg 391.

[42] "The Pragmatic Pivot: Validating an NCCL Topology Workaround for GPU NUMA" — NCCL validation at msg 392.

[43] "The Sysfs Gambit: A Desperate Attempt to Fix GPU NUMA Topology from Inside the VM" — Sysfs approach at msg 393.

[44] "The Sysfs Hack: Manually Patching NUMA Affinity for Virtualized GPUs" — Sysfs NUMA writes at msg 394.

[45] "The Moment of Verification: When Manual NUMA Node Assignments Failed to Move the Needle" — Verification that sysfs didn't work at msg 395.

[46] "The Sysfs Mirage: When Software Topology Collides with Hardware Reality" — Sysfs mirage at msg 396.

[47] "The Todo That Closed a Chapter: How One Status Update Captured the Limits of Virtualized GPU P2P" — Status update at msg 397.

[48] "The Moment of Acceptance: Drawing a Line Under Virtualization's Hard Limits" — Acceptance at msg 398.

[49] "The BIOS Question: A Pivot Point in the P2P DMA Investigation" — BIOS question at msg 399.

[50] "The BIOS Research Pivot: How an AI Assistant Sought Hardware Configuration Knowledge" — BIOS research at msg 400.

[51] "The BIOS Settings Inquiry: When an NVIDIA GPU Server Leads to AMD Documentation" — BIOS inquiry at msg 401.

[52] "The Hidden Lever: BIOS Configuration as the Final Frontier in Multi-GPU Inference Performance" — BIOS deep dive at msg 402.

[53] "The P2P Question: When Security Isolation Meets Hardware Topology" — P2P ACS question at msg 403.

[54] "The Moment the P2P Dream Died: Understanding ACS, IOMMU Groups, and Hardware Topology" — ACS explanation at msg 404.

[55] "The Silence of the Tool: A 15-Second Timeout That Speaks Volumes" — SSH timeout at msg 405.

[56] "The Silence Between Commands: An Empty Message at a Critical Juncture" — Empty message at msg 406.

[57] "The Art of the Gentle Redirect: How Two Words Rescued a Debugging Session" — Redirect at msg 407.

[58] "The ACS Paradox: Why Disabling PCIe Access Control Services Might (or Might Not) Enable GPU P2P" — ACS paradox at msg 408.

[59] "\"System Still Booting\" — A Pivotal Question at the Crossroads of GPU Virtualization" — Booting question at msg 409.

[60] "The Validation Playbook: Diagnosing GPU P2P Topology After an ACS Disable Attempt" — ACS validation playbook at msg 410.

[61] "The Moment the IOMMU Groups Refused to Merge: A Turning Point in the P2P DMA Investigation" — IOMMU groups didn't merge at msg 411.

[62] "When Disabling ACS Couldn't Bridge the IOMMU Gap" — ACS failure analysis at msg 412.

[63] "The Anatomy of a Hardware Question: \"Is the Root Complex Situation Down to the CPU or the Motherboard?\"" — Root complex question at msg 413.

[64] "The Architecture of Isolation: Why PCIe Topology Dooms GPU P2P in Virtualized Environments" — Architecture analysis at msg 414.

[65] "The Desperate Question: \"Are there hacky/insecure ways to get SYS/NODE in kvm?\"" — The hacky question at msg 415.

[66] "When the Hacks Begin: A Pivot from Configuration to Exploitation" — Hack research at msg 416.

[67] "The Silence That Speaks Volumes: An Empty Message at the Crossroads of Hardware Reality" — Empty message at msg 417.