A Linux kernel sizing bug can prevent a system from mapping multiple 32 GB Resizable BARs (Base Address Registers) when they are connected behind a PCIe switch, effectively blocking high-performance peer-to-peer (P2P) communication between GPUs. This occurs because the kernel underestimates the amount of address space required to accommodate the alignment gaps between large memory blocks and small register windows.

The Alignment Gap Problem

When a GPU uses Resizable BAR, it maps its entire VRAM—such as 32 GB—into the CPU's address space. However, many GPUs also require a small 'doorbell' BAR for driver communication. Because these large BARs must start on specific boundaries (e.g., 32 GB), a 2 MB doorbell placed immediately after a 32 GB BAR still forces the next device to start at the next 32 GB increment.

The Linux 7.0 kernel contains a regression in the `pbus_size_mem()` function. It calculates the switch's total window by summing the sizes of its children. Because it treats these as a simple sum rather than accounting for the alignment gaps, it believes the cards will fit into a smaller space than they actually occupy, leading to 'can't assign; no space' errors.

A cartoon of a parking lot with a sign saying 'switch window' and four bays, showing two R9700 limousines parked inside while others wait outside.
A conceptual illustration of the 'can't assign; no space' error caused by the kernel's failure to account for alignment gaps.doug.sh

This illustration provides a visual metaphor for the sizing bug where the kernel believes the available space is sufficient despite the actual alignment requirements.

“The kernel gave the switch a window of about 128.6 GB. With the doorbell placed after each BAR, the way Linux 7.0 lays them out, the four windows span 224 GB (three 64 GB slots plus the last card’s 32 GB and its doorbell).”

— Fitting Four 32 GB Resizable BARs Behind a PCIe Switch on Linux
A technical diagram showing three different ways to map GPU memory windows in a PCIe switch, illustrating the kernel's calculation error versus the module's padding solution.
Comparison of how the Linux 7.0 kernel calculates switch windows versus the manual padding method used by the gpu-rebar-layout module.doug.sh

This diagram illustrates the specific alignment gap problem where the kernel's 'plain sum' calculation fails to account for the 32 GB padding required by large BARs.

Bypassing the Kernel Sizing Bug

To resolve this, a custom kernel module (`gpu-rebar-layout`) operates within the initramfs, the tiny filesystem the kernel starts from before any GPU drivers are loaded. The module identifies the target GPUs, sets their BAR0 size to the maximum supported (e.g., 32 GB), and then removes and rescans the root ports above the PCIe switch.

During this rescan, the module manually raises the alignment of every smaller memory BAR to match the largest BAR on that segment. This ensures that each R9700 window occupies exactly 64 GB of address space, allowing the kernel's allocator to successfully place all devices without overlapping or running out of space.

Performance Gains and Trade-offs

Correctly mapping these BARs is critical for peer-to-peer (P2P) communication, which allows GPUs to copy data to each other without involving the CPU. In testing with four AMD Radeon AI PRO R9700s, this configuration achieved 14.0 GB/s per pair, with four cards copying in a ring at a combined 54.7 GB/s.

The workaround involves specific trade-offs: it must be loaded very early in the boot process, and it may require disabling GPU audio functions to free up more address space. Additionally, while a 14-patch series of fixes is currently being developed for the Linux kernel to address this sizing bug properly, the module remains a necessary stopgap for current versions.

What Hacker News readers are saying

  • Alternative: Commenters noted that the author of the post explained that they developed the module to enable peer-to-peer transfers between four GPUs, noting that disabling this feature significantly reduced performance during prefill tasks. comment ↗
  • Technical note: One commenter clarified that the issue stems from firmware limitations on certain motherboards, where the BIOS restricts the available address space for PCI devices, causing large BARs to overlap and exceed available slots. comment ↗
  • Skeptical: Several commenters expressed frustration that software layers and hidden configurations are preventing the hardware from utilizing its full physical capabilities, questioning why such a large virtual address space is not being managed more easily. comment ↗

Summarized opinions from the Hacker News thread, not verified facts. Read the full discussion ↗