Kurzfassung
Cthulhus PowerColor Radeon RX 9060 XT konnte leichte Spiele stundenlang ausführen, während schwere Titel immer wieder Stalls, Blackscreens und teilweise einen vollständigen GPU-Hard-Lock mit 100 Prozent Lüfterdrehzahl auslösten.
Nach einer langen Software-Fehlersuche stürzte Mesa 26.2.4 auf dem alten PCIe-Aufbau weiterhin innerhalb weniger Sekunden ab. Danach vereinfachte ich den Hardwarepfad in einem Wartungsdurchgang: GPU direkt ins Mainboard, Corsair-Riser raus, Intel-10-GbE-Karte raus und die BIOS-Linkeinstellung von erzwungenem Gen3 zurück auf Gen4/Auto.
Der äußere GPU-Link wechselte von 8 GT/s x8 auf 16 GT/s x16. In diesem Zustand lief S.T.A.L.K.E.R. 2 ungefähr 25 Minuten ohne Traversal-Stall oder Blackscreen, gefolgt von rund 20 Minuten Arma 3 ohne ein einziges Problem.
Das ist unser stärkster Hinweis bisher, aber noch kein endgültiger Root-Cause-Beweis. Mehrere Hardwarevariablen änderten sich gleichzeitig. Die Daten zeigen, dass der PCIe-/Topologie-Wechsel relevant ist; sie sagen noch nicht, ob Riser, Lane-Aufteilung, Gen3 gegen Gen4, die entfernte 10-GbE-Karte oder eine Kombination daraus entscheidend war. Mesa 26.2.4 kann ebenfalls beitragen, war auf der alten Topologie allein aber nicht ausreichend.
Die Maschine und das Fehlerbild
Die Workstation ist Cthulhu: Ryzen 7 5800X3D, PowerColor Radeon RX 9060 XT 16 GiB, Gigabyte B550 VISION D, NixOS, Plasma/Wayland und zwei Monitore. Die GPU meldet sich als Navi44 / RDNA4 / GFX1200, PCI-ID 1002:7590, Subsystem 148c:2437.
Der Fehler war nie nur ein sauberer einzelner Bug. Genau diese Trennung wurde später wichtig.
Traversal-Stalls
S.T.A.L.K.E.R. 2 konnte im Stand schießen, nachladen und sich umsehen. Beim Bewegen durch die Welt kamen jedoch ein- bis mehrsekündige Hänger. Bei aufgezeichneten Stalls erschien oft kein amdgpu-Timeout im Kernel-Log.
Blackscreen, Ton lebt
Manche Läufe verloren das Bild, während der Ton weiterlief und die GPU-Lüfter normal blieben. Das sah eher nach Display-/Presentation- oder Render-Wedge aus als nach dem katastrophalen Fehler.
Blackscreen, Lüfter 100%
Der üble Fall. Schwere Spiele konnten beide Monitore schwarz schalten, die GPU-Lüfter auf Vollgas setzen und einen harten Neustart erzwingen.
Arma 3 als brutaler Trigger
Arma wurde zum reproduzierbarsten Test: Beim Joinen konnte der Hard-Lock fast sofort auftreten.
Der Kernel hinterließ endlich einen Fingerabdruck
Manche Abstürze starben so hart, dass praktisch nichts im Journal landete. Andere lieferten eine deutlich bessere Signatur. Interessant war nicht nur der Timeout des Grafik-Rings; auch die Wiederherstellung scheiterte:
amdgpu: ring gfx_0.0.0 timeout MES(1) failed to respond to msg=RESET failed to reset legacy queue reset via MES failed and try pipe reset -110 The CPFW hasn't support pipe reset yet. GPU reset begin! amdgpu: device lost from bus! GPU Recovery Failed: -19
Damit änderte sich das Arbeitsmodell. Der MES-Fehler konnte ein Recovery-Fehler nach dem eigentlichen Hang sein und musste nicht die ursprüngliche Ursache darstellen.
Firmware inventarisieren statt raten
Bevor pauschal „alte Firmware“ beschuldigt wurde, lasen wir aus, was die Karte wirklich geladen hatte:
ME feature 29 firmware 0x00000c12 PFP feature 29 firmware 0x00000c76 MEC feature 29 firmware 0x00000d7a SMC firmware 0x00664700 (102.71.0) DMCUB firmware 0x0a004b00 MES feature 1 firmware 0x00000093
Das war wichtig, weil die Fehlersuche sonst schnell zu „neueres Blob installieren und hoffen“ geworden wäre. Das geladene SMU war nicht offensichtlich veraltet; neuere Upstream-Display-Firmware blieb eher für die Blackscreens mit normalem Lüfter interessant.
Das Terminal wurde zum Laborbuch
Der nützlichste Teil der ganzen Fehlersuche war, die Befehle langweilig und reproduzierbar zu halten. Immer nur ein Read-only-Check auf einmal machte es viel leichter zu erkennen, ob eine neue Theorie wirklich etwas verändert hatte.
journalctl -b -1 -k --no-pager | grep -Ei 'amdgpu|ring|timeout|reset|mes|device lost|gpu recovery|gpuvm|fault|pcie|aer' | tail -n 100 sudo cat /sys/kernel/debug/dri/0000:55:00.0/amdgpu_firmware_info nix-shell -p pciutils --run 'sudo lspci -s 00:03.1 -vv' vulkaninfo --summary | grep -E 'driverName|driverInfo'
Diese vier Checks beantworteten vier unterschiedliche Fragen: Was ist ausgefallen? Welche Firmware ist wirklich geladen? Wie wurde PCIe tatsächlich ausgehandelt? Und welchen Mesa-Treiber sieht ein frisch gestarteter Prozess? Genau diese Trennung verhinderte mehrere falsche Schlussfolgerungen.
Was wir getestet haben — und was es nicht gelöst hat
Die Regel war einfach: möglichst eine Softwarevariable ändern, denselben Workload reproduzieren, den echten Fehler lesen und nicht nach einem etwas längeren Lauf voreilig „fixed“ sagen.
Kernel
Linux 7.2.8 blieb die bevorzugte Basis. Linux 6.18.54 war schlechter: S.T.A.L.K.E.R. konnte beim Einstieg sofort mit 100%-Lüftern schwarz werden. Linux 7.3-rc6 blackscreente trotz relevanter GFX12-Fixes ebenfalls fast sofort beim ersten Bewegungstest.
Älteres Mesa
Mesa 25.1.7 war kein bekannter guter Rückfallpunkt. An einer Stelle, an der 26.1.8 normalerweise stallte, lieferte 25.1.7 einen dauerhaften Blackscreen bei weiterlaufendem Ton.
Scheduler und Power-Knöpfe
amdgpu.uni_mes=0, amdgpu.async_gfx_ring=0, GFXOFF-Inhibition, synchrone RADV-Shader und GPU-Power-Limits von 112 W bis zu normalen 160 W entfernten das Problem nicht.
Rendering-Pfade
Arma stürzte auch mit PROTON_USE_WINED3D=1 ab. DXVK/Vulkan war für die katastrophale Fehlerklasse also nicht erforderlich. RADV_DEBUG=nodcc rettete S.T.A.L.K.E.R. ebenfalls nicht.
Storage
Das Spiel wanderte von den SATA-Spiel-SSDs auf NVMe. Die Traversal-Stalls blieben. Die Samsung-SATA-Laufwerke haben echte Transportfehler, das ist aber ein separates Wartungsthema und keine vollständige Erklärung für den GPU-Hard-Lock.
Spezifische Upstream-Workarounds
Ein gezielter GFX12-SDMA/DCC-Kernel-Workaround wurde zurückportiert und getestet. Die S.T.A.L.K.E.R.-Stalls blieben unverändert. Auch deaktiviertes Steam-Shader-Pre-Caching verhinderte den nächsten Hard-Lock nicht.
ASPM sah vielversprechend aus — bis wir gemessen haben
Ein sehr ähnlicher PowerColor-RX-9060-XT-Fall wurde mit global deaktiviertem PCIe-ASPM stabil. Sogar die Subsystem-ID passte zu unserer Karte. Also wurde das ordentlich geprüft.
Statt blind noch einen Bootparameter hinzuzufügen, wurden alle relevanten Hops ausgelesen. Root-Port, Upstream-Switch, Downstream-Switch und GPU meldeten jeweils:
LnkCtl: ASPM Disabled
Auch die L1-Substates waren aus. Damit war pcie_aspm=off für Cthulhu kein guter Kandidat: Der relevante Pfad lief ohnehin schon ohne ASPM.
Dann wehrte sich Mesa 26.2.4 auf sehr NixOS-artige Weise
Der erste Versuch, Mesa 26.2.4 direkt aus einem neueren nixpkgs-Snapshot zu übernehmen, lieferte ein perfektes Beispiel dafür, warum gemischte Package-Sets gefährlich sein können:
libm.so.6: version 'GLIBC_2.44' not found required by ... libLLVM.so.21.1 loader_icd_scan: Failed loading ... libvulkan_radeon.so
Kein GPU-Mysterium — schlicht ein ABI-Mismatch. Der Versuch wurde sofort zurückgerollt.
Danach wurde Mesa 26.2.4 aus dem Upstream-Quellstand gegen Cthulhus vorhandenen NixOS-Paketstand und Toolchain gebaut, jeweils für 64- und 32-Bit-Grafik. Anschließend lud RADV sauber:
driverName = radv driverInfo = Mesa 26.2.4 driverName = llvmpipe driverInfo = Mesa 26.2.4 (LLVM 21.1.8)
Dann ging S.T.A.L.K.E.R. ins Spiel — und hardlockte auf dem alten PCIe-Aufbau trotzdem nach wenigen Sekunden. Ein sehr wertvolles negatives Ergebnis: Mesa 26.2.4 allein war nicht der Fix.
Die Hardware wurde radikal vereinfacht
Zu diesem Zeitpunkt hatten wir den Softwarebaum oft genug geschüttelt. Statt weitere zwölf Reboots zu produzieren, wurde der physische Pfad in einem einzigen Shutdown so weit wie möglich vereinfacht:
GPU: Corsair-Riser → raus GPU: indirekte Montage → direkt im Mainboard Intel Dual-Port 10 GbE → für den Test raus BIOS PCIe-Modus: erzwungenes Gen3 → Gen4 / Auto Software: Linux 7.2.8 + Mesa 26.2.4 → unverändert
Das war bewusst kein Ein-Variablen-Test. Die Frage war eine andere: Wird die Maschine stabil, wenn wir die PCIe-Umgebung maximal vereinfachen?
Vorher lief der äußere GPU-Link so:
LnkSta: Speed 8GT/s (downgraded), Width x8 (downgraded)
Nach dem direkten Einbau:
00:03.1 root port LnkCap: Speed 16GT/s, Width x16 LnkSta: Speed 16GT/s, Width x16 53:00.0 GPU upstream port LnkSta: Speed 16GT/s (downgraded), Width x16
Die Karte zeigt intern weiterhin ihre AMD-Switch-Funktionen, aber der Mainboard-seitige Pfad hatte sich von PCIe 3.0 x8 auf PCIe 4.0 x16 verändert.
Das erste Ergebnis, das sich wirklich anders anfühlte
S.T.A.L.K.E.R. 2 konnte vorher innerhalb weniger Sekunden sterben. Im vereinfachten PCIe-4.0-x16-Aufbau lief es ungefähr 25 Minuten ohne Traversal-Stall, ohne Blackscreen und ohne 100%-Lüfter-Hard-Lock.
Arma 3 war unser brutalster Reproducer. Aus einem Blitztest wurden rund 20 Minuten normales Spielen — ohne ein einziges Problem.
Nicht „der Crash kam etwas später“. Nicht „das Power-Limit änderte nur das Symptom“. Die beiden Workloads, die den Fehler immer wieder zuverlässig sichtbar gemacht hatten, verhielten sich plötzlich normal.
Noch ein PCIe-Detail: Sticky Lane Errors
Nach dem Boot des direkten Gen4-x16-Aufbaus zeigte der Root-Port zunächst klebende Lane-Error-Bits auf den Lanes 3, 7, 11 und 15:
LnkSta: Speed 16GT/s, Width x16 LaneErrStat: LaneErr at lane: 3 7 11 15
Solche Bits können vom Link-Training übrig bleiben. Deshalb wurden sie für eine saubere Ausgangsbasis gelöscht. Der Read-back zeigte danach:
00000000
Entscheidend ist nicht, ob das Training irgendwann einmal ein Bit gesetzt hat. Entscheidend ist, ob nach längerer Gaming-Last neue Lane-Fehler auftauchen. Genau dieser Test steht noch aus.
Was ich aktuell vermute
Die stärksten Hinweise zeigen momentan auf den PCIe-Pfad / die Lane-Topologie / die Riser-Umgebung als Teil des echten Problems. Dazu passt eine ältere Beobachtung aus der Arch-Zeit: Damals verschwanden separate WoW-Classic-Blackscreens, nachdem die GPU ohne Riser direkt im Board saß.
Die Intel-10-GbE-Karte ist für mich nicht der Hauptverdächtige. Das NAS auf der Gegenseite war bei diesen Tests nicht einmal aktiv; Netzwerktraffic spielte also keine Rolle. Trotzdem kann eine installierte Karte die PCIe-Lane-Aufteilung beeinflussen. Wissenschaftlich ausgeschlossen ist sie damit noch nicht.
Auch dass Windows auf dem alten physischen Aufbau stabil lief, ist wichtig. Das spricht gegen die einfache Aussage „der Riser ist kaputt“. Ein grenzwertiger Link, eine Lane-Layout-Interaktion oder ein Reset-/Power-State-Randfall kann von Windows und Linux unterschiedlich toleriert werden. Der Linux-GFX12-Stack könnte schlicht deutlich weniger gnädig reagieren, wenn die GPU nicht mehr antwortet.
Mesa 26.2.4 kann ebenfalls helfen, aber die Beweislage ist asymmetrisch: Auf der alten Topologie stürzte es schnell ab; der neue Aufbau wurde noch nicht mit Mesa 26.1.8 gegengeprüft. Die faire Aussage lautet deshalb: PCIe-/Topologie-Wechsel: stark belastet; Mesa 26.2.4: plausibler Mitspieler; exakte Root Cause: noch offen.
Wie es weitergeht
Der nächste Schritt ist absichtlich langweilig: den stabilen Zustand erstmal in Ruhe lassen und längere Sessions spielen. Danach wird LaneErrStat erneut ausgelesen. Bleibt alles sauber, kommt zuerst die Intel-10-GbE-Karte wieder rein, während die GPU direkt mit Gen4 x16 bleibt. Ist das weiterhin stabil, rutscht die NIC weit nach unten. Riser und x8-/Bifurcation-Pfad können danach getrennt isoliert werden.
Kein „fünf Kernelparameter ändern und rebooten“-Roulette mehr. Wir haben endlich einen brauchbaren Referenzzustand.
Lehre
Der größte Fehler wäre gewesen, jeden Blackscreen als denselben Bug zu behandeln.
Eine Fehlerklasse sah nach Display-/Render-Wedge aus. Eine andere erzeugte einen Graphics-Ring-Timeout, danach scheiternde MES-Recovery und schließlich den Verlust des Geräts. Die Traversal-Stalls konnten wiederum ohne beides auftreten.
Erst nachdem diese Dinge getrennt wurden, wurde die Fehlersuche wirklich nützlich: die Ebene messen, die tatsächlich ausfällt, funktionierende Variablen einfrieren und erst dann die nächste ändern.
Und nach gefühlt Neustart Nummer 224 ist der wertvollste Befehl manchmal kein weiterer Kernelparameter.
Manchmal ist es ein Schraubendreher.