[GSD-13433] [xe] Small-BAR configs are rejected while i915 allows them — could this be a debug key?
- Dominant language
- C++
- Stars
- 1.4k
- Forks
- 300
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
On the `xe` driver, Level Zero refuses to initialize a discrete GPU when a small BAR is detected, and the device disappears from enumeration entirely. On `i915` the same condition is explicitly allowed. The difference is a hardcoded constant in each `IoctlHelper`, not a policy that can be overridden.
I would like to ask whether this asymmetry is intentional for `xe`, and whether it would be reasonable to gate it behind a debug key so that small-BAR configurations can at least be attempted.
## Where this happens
`shared/source/os_interface/linux/drm_neo.cpp`:
```cpp
} else if (getMemoryInfo()->isSmallBarDetected()) {
IoFunctions::fprintf(stderr, "WARNING: Resizable BAR not detected for device %s\n", getPciPath().c_str());
if (!ioctlHelper->isSmallBarConfigAllowed()) {
return -1;
}
}
```
`smallBarDetected` is computed in `shared/source/os_interface/linux/memory_info.cpp`:
```cpp
smallBarDetected = std::ranges::any_of(localMemoryRegions,
[](const MemoryRegion ®ion) {
return (region.cpuVisibleSize && region.cpuVisibleSize < region.probedSize);
});
```
And the two implementations differ:
```cpp
// shared/source/os_interface/linux/ioctl_helper.h (IoctlHelperI915)
bool isSmallBarConfigAllowed() const override { return true; }
// shared/source/os_interface/linux/xe/ioctl_helper_xe.h (IoctlHelperXe)
bool isSmallBarConfigAllowed() const override { return false; }
```
So on `i915` a small-BAR device continues past the check with a warning, and on `xe` it returns `-1` and is never enumerated. Since Battlemage and later are `xe`-only, there is no way to fall back to the permissive path.
## My case
An Arc B580 in a Thunderbolt/USB4 enclosure. The card enumerates on the PCI bus, binds to `xe`, and its edge connector trains at the expected `16GT/s x4` for a USB4 tunnel. Only the BAR stays small:
```
Device 0000:54:00.0 (Intel Arc B580, 12GB)
BAR2 0x2030000000, 256 MiB
resize caps 0x7f00 (256MB .. 16GB advertised)
driver xe
NEO 26.31.39395.13
kernel 7.0.0-31
```
```
$ lspci -vv
B580 BAR 2: current size: 256MB, supported: 256MB 512MB 1GB 2GB 4GB 8GB 16GB
iGPU BAR 2: current size: 256MB, supported: 256MB
```
The BAR cannot be grown on this host. Firmware reserves only a few hundred MB of prefetchable space per tunneled PCIe root port (I measured 448 MiB and 711 MiB across boots), and the BAR lands at the start of that window, so it is only 256MB-aligned and `pci_resize_resource` rejects every size from 512MB upward. I raised this separately on linux-pci, and Mika Westerberg confirmed the shape of it:
> Typically there is just certain amount of resources allocated for each PCIe root port that gets tunneled so the way to do this is to increase that in the BIOS. Having said that most of the vendors don't actually allow it to be changed.
https://lore.kernel.org/linux-pci/20260911090800.GZ106095@black.igk.intel.com/
I have filed a request with the laptop vendor as well, but that path is slow and may not land at all. Meanwhile the card is completely unusable for compute even though nothing else about it is wrong.
## Why I think a small BAR may be acceptable for my workload
I understand the reasoning in the FAQ — that the driver does not initialize without Resizable BAR in order to avoid a subpar experience. For interactive and graphics workloads that makes sense to me.
My workload is fine-tuning imitation-learning policies for robot manipulation — action-chunking transformers today, vision-language-action models next. Weights and activations live in device memory for the duration of training; the host writes batches in and reads scalars out. It is close to the least BAR-sensitive thing one can run on a GPU.
The integrated Arc 140V on the same machine has a 256MB BAR that cannot be resized at all (`supported: 256MB`), and it fine-tunes these policies without trouble — that is measured, at batch sizes up to 36 for my input shape. It is an integrated GPU sharing system memory rather than a discrete card with its own local memory, so it is not a strict equivalent. It is simply the closest evidence I have that a 256MB aperture is not by itself fatal to this kind of work.
I fully accept that performance may be poor, possibly much worse than a resizable-BAR configuration. I would like to be able to measure that rather than be unable to start.
## Questions
1. Is `isSmallBarConfigAllowed() == false` for `xe` a deliberate policy decision, or does it reflect a functional limitation in the `xe` path that does not exist on `i915`?
2. If it is policy, would you consider gating it behind a debug key — something like `AllowSmallBarConfig` read via `NEOReadDebugKeys=1` — so that users can opt in and accept the performance consequences?
3. If it is a functional limitation, is there a description of what breaks, so that it is clear this is not worth pursuing?
I checked the debug variables in `shared/source/debug_settings/debug_variables_base.inl` and could not find an existing key that reaches this branch; `ForceLocalMemoryAccessMode`, `EnableLocalMemory` and `OverrideGpuAddressSpace` all leave the check in place, which matches the code above since the branch does not consult `debugManager`.
Thanks for reading, and thanks for the runtime.
Contributor guide
Research direction
Start at the small-BAR check in shared/source/os_interface/linux/drm_neo.cpp, then compare isSmallBarConfigAllowed() in shared/source/os_interface/linux/ioctl_helper.h and shared/source/os_interface/linux/xe/ioctl_helper_xe.h. Read shared/source/debug_settings/debug_variables_base.inl to determine how a debug key could reach this path. Done means the xe policy or limitation is established and the opt-in behavior, if accepted, is defined and covered by the project’s relevant tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, linux
- Domain
- devtools, operating-systems, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100