← Back to the blog · Published · Leer en español · Source: Interactive artifact “Avoiding Xid 109” (Claude)
Avoiding Xid 109 on NVIDIA under Linux without rebuilding the driver
When a game under Proton dies with “Xid 109 CTX SWITCH TIMEOUT” after a few maps or while precaching shaders: how to recognise it, the one DXVK line that avoids it, how to verify, and which data would help NVIDIA.
When a game under Proton dies with NVRM: Xid 109 … CTX SWITCH TIMEOUT after a few maps or while precaching shaders, and the driver is NVIDIA’s open kernel modules, these are the essentials: how to recognise it, the one line that avoids it, how to verify, and which data would help NVIDIA. No driver recompilation needed, Secure Boot stays untouched, and it works for Steam, Lutris, Heroic, Bottles and plain Wine. It is a mitigation, not a fix.
Result of an independent investigation (August–September 2026) on a Lenovo LOQ 15ARP9 with an RTX 3050 6 GB, open modules 615.71.09, Proton 11.0-100 (DXVK a6764047). No proprietary binaries were inspected; every claim is traceable to public source or to the machine’s logs. Not affiliated with NVIDIA.
1. Recognise it: is this the failure?
Yes, if all three hold. Check in a terminal while the game is running:
journalctl -kf | grep -E 'Xid|vaddr < \(baseVirtAddr'
- Before the crash there is a burst (dozens per second) of
NVRM: nvAssertFailedNoLog: Assertion failed: vaddr < (baseVirtAddr + virtSize) @ dma.c:159(dma.c:159) - Seconds later:
NVRM: Xid (PCI:…): 109, pid=…, name=<game>.exe, Ch 0000000x, … CTX SWITCH TIMEOUT. The GPU keeps working; only the game loses its context. - It always happens at the same load point: after ~3 maps, while precaching shaders, or when the game’s own VRAM counter reaches a fixed value (on an RTX 3050 6 GB, ~4.8 GB). Lowering textures makes no difference.
What it is. NVIDIA’s proprietary user-mode driver keeps shader code in a fixed 1.5 GiB virtual arena per Vulkan process; when it fills up, the driver keeps asking to map past the end, the kernel module rejects every request (that is the assertion) and the graphics engine stalls until the GSP firmware declares Xid 109. With the open modules the GSP cannot be disabled (NVreg_EnableGpuFirmware=0 does not apply).
2. Avoid it: the line
dxvk.enableGraphicsPipelineLibrary = True
With the default (Auto) DXVK already uses Graphics Pipeline Library, but it also compiles an optimised variant of every pipeline in the background; that extra code is what fills the 1.5 GiB arena. With True the variants are not compiled and the arena never fills.
Steam (Proton)
Option A — in the game’s launch options (independent of the working directory; the most reliable way):
DXVK_CONFIG="dxvk.enableGraphicsPipelineLibrary=True" %command%
If you already have other options in DXVK_CONFIG, separate them with ;: DXVK_CONFIG="dxgi.maxFrameRate=141;dxvk.enableGraphicsPipelineLibrary=True".
Option B — a dxvk.conf file in the directory the executable starts from (for Steam, the game’s install directory) containing that single line.
Lutris, Heroic, Bottles, plain Wine
- Lutris: Configure → Environment variables →
DXVK_CONFIG=dxvk.enableGraphicsPipelineLibrary=True. - Heroic: Game settings → Environment variables → same key and value.
- Bottles: Bottle preferences → Environment variables → same key and value.
- Plain Wine:
DXVK_CONFIG="dxvk.enableGraphicsPipelineLibrary=True" wine game.exe, orDXVK_CONFIG_FILE=/path/dxvk.conf.
Scope
- Applies to D3D8/9/10/11 games translated by DXVK (most games under Proton). For D3D12 (vkd3d-proton) and native Vulkan this option does not exist; if you see the same assertion with them, it is the same driver bug without this shortcut.
- Cost: linked pipelines carry no cross-stage optimisation; slightly lower per-shader performance. In the test session the GPU stayed at 100 % utilisation and at its power ceiling; the fps impact was not measured.
- Undo: remove the line. Nothing on the system is touched.
3. Verify
# 1) DXVK read the option (once; then remove it — it writes logs into the game directory)
DXVK_LOG_LEVEL=info DXVK_CONFIG="dxvk.enableGraphicsPipelineLibrary=True" %command%
# in <game>_d3d11.log or _dxgi.log: info: Found config env: dxvk.enableGraphicsPipelineLibrary=True
# 2) no burst and no Xid during the load that used to fail
journalctl -kf | grep -E 'Xid|vaddr < \(baseVirtAddr' # must stay empty
Measured reference (RTX 3050 6 GB Laptop, open modules 615.71.09, Proton 11.0-100, Overwatch 2): before, failure after 6–9 min of precaching in 4 of 4 sessions; with the line, 52 min 49 s of continuous map rotation (≈15 maps) without a single assertion or Xid, at the same VRAM level at which it used to die.
4. What was tried and changes nothing
| Attempt | Measured result |
|---|---|
Capping the VRAM the game sees (dxgi.maxDeviceMemory) | identical failure at 7 min |
| Lower textures / quality to keep VRAM away from the ceiling | the ceiling is not VRAM: it is the 1.5 GiB shader-code arena |
| More swap, no OOM, power profile, power limit, temperature | ruled out with data: the failure happens with 0 OOM, GPU at 90 W and 70 °C without throttling |
clearcpuid=umip (anti-cheat executing SIDT) | removes an emulation storm on the CPU, but Xid 109 continues |
Disabling the GSP (NVreg_EnableGpuFirmware=0) | impossible with open modules; would require the proprietary module |
| Patching the open kernel module (MIT) | it can diagnose, not fix: the kernel accepts every reservation the driver asks for, and when the kernel maps on its behalf and returns the address, the user-mode driver ignores it (immediate Xid 13) |
5. If the game shows 0 °C for the GPU (optional)
Under Wine/Proton the game’s telemetry goes NvAPI (dxvk-nvapi) → nvml.dll. Proton ships no nvml.dll; you build wine-nvml and copy it into the prefix. The rule that saves the scare: every Proton version change may recreate the prefix and delete the copy; it is not the driver. A wrapper in the launch options restores it automatically:
#!/usr/bin/env bash # ~/.local/bin/ow-pre — before %command% in the launch options
SRC="$HOME/.local/share/wine-nvml/usr/lib64/wine/x86_64-windows/nvml.dll"
PFX="$STEAM_COMPAT_DATA_PATH/pfx/drive_c/windows/system32"
[[ -f $SRC && -d $PFX ]] && ! cmp -s "$SRC" "$PFX/nvml.dll" && cp "$SRC" "$PFX/nvml.dll"
exec "$@"
WINEDLLPATH=$HOME/.local/share/wine-nvml/usr/lib64/wine DXVK_CONFIG="dxvk.enableGraphicsPipelineLibrary=True" ~/.local/bin/ow-pre %command%
Verify: PROTON_LOG=1 and grep -i thermal ~/steam-<appid>.log → NvAPI_GPU_GetThermalSettings: OK.
6. For NVIDIA: which data would help fix it
Users cannot fix the proprietary driver, but they can give NVIDIA what release builds do not show today (the assertion is anonymous). What this investigation already establishes, with sanitised logs and cited source:
- A single
NV50_MEMORY_VIRTUALreservation of0x60000000bytes per Vulkan instance (flags0x40ac10d,VIRTUAL|SPARSE|USE_BEGIN_END|…), never a second one; the kernel refused no reservation. - When it fills, mapping requests at
DmaOffset = size,size+0x10000… (bump allocator) from the pipeline-compilation thread; the kernel rejects them withNV_ERR_INVALID_OFFSET; Xid 109 follows 17–206 s later. - If the kernel maps into another VA and returns it in
dmaOffset, the driver still usesbase+offset→Xid 13 Shader Program Header Error: the objects are shader programs. - With GPL libraries only (no optimised variants) the arena does not fill in ≥ 53 min: the overflowing volume is that of the optimised pipelines.
- Secondary observation: a mapping onto an already-mapped VA (
gpu_vaspace.c:4502,NV_ERR_INVALID_ARGUMENT), non-fatal.
Expected fix in the user-mode driver: reserve another arena when the current one fills, or fail pipeline creation with VK_ERROR_OUT_OF_DEVICE_MEMORY. References: NVIDIA bug 5052028 (forum thread 283722); issues #1140, #1187, #1282, #1364 on NVIDIA/open-gpu-kernel-modules.
If you want to contribute your own case
nvidia-smi --query-gpu=name,driver_version --format=csv,noheader; uname -r; grep EnableGpuFirmware /proc/driver/nvidia/params
journalctl -k -b -o short-iso-precise | grep -E 'Xid|dma.c:159' | sed 's/ [a-z0-9-]* kernel:/ host kernel:/' > xid109-journal.txt
nvidia-smi --query-gpu=timestamp,memory.used,power.draw,temperature.gpu,clocks.sm --format=csv -l 1 > xid109-smi.csv # during the load
Plus the Proton/DXVK version, the game and how long it takes to fail. No hostname, no GPU UUID.
Source of this post: interactive artifact “Avoiding Xid 109” · Spanish version. The diagnostic patches, sanitised evidence and full report are published in the project repository.
← Back to the blog · Leer en español · Source: Interactive artifact “Avoiding Xid 109” (Claude)