Veröffentlicht: Juli 17, 2026
CS2 hat mein System mehrfach hart abgeschossen. Nicht nur das Spiel — der ganze Fenstermanager war weg, Steam tot, VLC tot. Alles weg außer dem Cursor. Ich habe den Fix gefunden, eingebaut, neugestartet — und der Crash passierte wieder. Der Fix war aktiv, aber GRUB hat ihn nie gelesen. Hier ist warum.
Das eigentliche Problem: CS2 killt den GPU-Ring
Das dmesg-Log erzählt die Geschichte ziemlich klar:
amdgpu: ring gfx_0.0.0 timeout — Process MainThrd / thread dxvk-submit
amdgpu: MES failed to respond to msg=RESET
amdgpu: Ring gfx_0.0.0 reset failed
amdgpu: GPU reset begin! Source: 1
amdgpu: MODE1 reset
amdgpu: VRAM is lost due to GPU reset!
kwin_wayland_wrapper: amdgpu: The CS has cancelled because the context is lost.
DXVK schickt einen Submit an den GPU-Ring → Ring-Timeout → AMD MES soll resetten → MES antwortet nicht → Hardware-Reset → VRAM-Verlust → XWayland bricht weg → alle X11-Apps (Steam, VLC, …) sterben → plasmashell / KWin crashen.
Eine Kaskade. Und der Auslöser sitzt tief in der GPU-Firmware.
Was ist RDNA3 MES?
MES steht für Micro Engine Scheduler — eine kleine Firmware, die seit RDNA3 (RX 7000er-Serie) auf der GPU läuft und Command-Submission und GPU-Ring-Management übernimmt. Klingt gut, hat aber unter DXVK-Last auf aktuellen Linux-Kerneln bekannte Hang-Probleme: MES beantwortet den Reset-Befehl schlicht nicht, was den gesamten GPU-Zustand korrumpiert.
Der Fix: amdgpu.mes=0 und s2idle
Zwei Parameter müssen in die Kernel-Commandline:
amdgpu.mes=0— schaltet den Firmware-basierten MES ab, nutzt stattdessen den älteren Software-Scheduler. Kein MES = kein MES-Hang.mem_sleep_default=s2idle— behebt einen separaten Bug: S3-Resume auf RDNA3 (Navi 31) ist strukturell kaputt in aktuellen Kerneln,s2idleumgeht das durch einen leichteren Suspend-Zustand.
Also rein in /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="nowatchdog nvme_load=YES splash loglevel=3 \
amdgpu.ppfeaturemask=0xffffffff amdgpu.sg_display=0 \
mem_sleep_default=s2idle amdgpu.mes=0"
Dann:
sudo grub-mkconfig -o /boot/grub/grub.cfg
Neugestartet. CS2 geöffnet. Crash.
Die Parameter waren immer noch nicht aktiv:
cat /proc/cmdline
# → kein mes=0, kein s2idle
Der eigentliche Bug: GRUB liest eine andere Datei
Auf CachyOS mit Btrfs und Snapper laufe ich von einem Snapshot, nicht vom Root-Subvolume. Das System bootet von @/.snapshots/284/snapshot. Wenn ich also /boot/grub/grub.cfg bearbeite, schreibe ich in die Snapshot-grub.cfg: @/.snapshots/284/snapshot/boot/grub/grub.cfg.
GRUB selbst startet aber früher — lange bevor das Betriebssystem weiß, welchen Snapshot es booten soll. GRUB liest vom Btrfs Default Subvolume, und der ist ID 5 (der @-Subvolume):
sudo btrfs subvolume get-default /
# → ID 5 (FS_TREE)
Das bedeutet: GRUB liest /@/boot/grub/grub.cfg. Nicht die Datei, die grub-mkconfig geschrieben hat.
Btrfs Subvolumes
Btrfs kennt kein klassisches Partitions-Konzept — stattdessen gibt es Subvolumes: unabhängige Teilbäume innerhalb desselben Dateisystems. CachyOS mit Snapper legt typischerweise @ als Haupt-Subvolume an und speichert Snapshots unter @/.snapshots/. Beim Booten wird dann nicht @, sondern ein bestimmter Snapshot als Rootfs gemountet. So kannst du bei einem kaputten Update einfach einen älteren Snapshot booten.
GRUB und der Btrfs FS_TREE
GRUB muss seine Konfigurationsdatei lesen, bevor irgendetwas anderes startet. Es kennt zu diesem Zeitpunkt keinen gemounteten Subvolume oder Snapshot — es liest direkt vom Btrfs Default Subvolume (FS_TREE, Subvolume-ID 5). Das ist fast immer @. Was das laufende System als /boot/grub/grub.cfg sieht, liegt aber im aktuell gemounteten Snapshot — eine völlig andere Datei.
Zur Bestätigung:
sudo mount -o subvolid=5 /dev/nvme1n1p2 /mnt/btrfs-root
grep 'mes=' /mnt/btrfs-root/@/boot/grub/grub.cfg
# → leer. Alte Parameter, kein mes=0.
Zwei Dateien. Beide heißen grub.cfg. GRUB liest die eine, grub-mkconfig schreibt in die andere.
Der einmalige Fix
Die aktuelle grub.cfg manuell in den @-Subvolume kopieren:
sudo mount -o subvolid=5 /dev/nvme1n1p2 /mnt/btrfs-root
sudo cp /boot/grub/grub.cfg /mnt/btrfs-root/@/boot/grub/grub.cfg
sudo cp /etc/default/grub /mnt/btrfs-root/@/etc/default/grub
sudo umount /mnt/btrfs-root
Neugestartet. cat /proc/cmdline zeigte jetzt amdgpu.mes=0. CS2 läuft stabil.
Die dauerhafte Lösung: Pacman Hook
Einmal manuell kopieren reicht, aber beim nächsten Kernel-Update passiert genau dasselbe wieder. Die Lösung ist ein Pacman Hook, der nach jedem grub-mkconfig-Lauf automatisch synchronisiert.
Zuerst das Script unter /usr/local/bin/grub-btrfs-sync:
#!/bin/bash
DEVICE=$(findmnt -n -o SOURCE / | sed 's/\[.*//')
MOUNT_POINT=$(mktemp -d /tmp/btrfs-root-XXXXXX)
cleanup() { umount "$MOUNT_POINT" 2>/dev/null; rmdir "$MOUNT_POINT" 2>/dev/null; }
trap cleanup EXIT
mount -o subvolid=5 "$DEVICE" "$MOUNT_POINT" || exit 1
cp /boot/grub/grub.cfg "$MOUNT_POINT/@/boot/grub/grub.cfg"
echo "grub-btrfs-sync: grub.cfg synced to @ subvolume"
sudo chmod +x /usr/local/bin/grub-btrfs-sync
Dann der Hook unter /etc/pacman.d/hooks/zz-grub-btrfs-sync.hook:
[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = File
Target = usr/lib/modules/*/vmlinuz
[Action]
Description = Syncing GRUB config to Btrfs @ subvolume...
Depends = grub
When = PostTransaction
Exec = /usr/local/bin/grub-btrfs-sync
Pacman Hooks
Pacman Hooks sind Shell-Befehle, die Pacman automatisch vor oder nach bestimmten Paket-Operationen ausführt. Sie werden als .hook-Dateien in /etc/pacman.d/hooks/ abgelegt. Das zz--Präfix sorgt dafür, dass dieser Hook alphabetisch nach dem offiziellen grub.hook läuft — der grub-mkconfig aufruft. So ist die neue grub.cfg bereits geschrieben, wenn unser Sync-Script startet.
Ab sofort: bei jedem Kernel-Update wird grub-mkconfig ausgeführt, dann direkt danach die grub.cfg in den @-Subvolume synchronisiert. Das Problem tritt nie wieder auf.
Zusammenfassung
Zwei Bugs, eine Reboot-Session:
- RX 7900 XTX / RDNA3:
amdgpu.mes=0deaktiviert den buggy Micro Engine Scheduler → keine GPU-Ring-Timeouts unter DXVK.mem_sleep_default=s2idleverhindert GPU-Freeze nach Suspend. - CachyOS + Btrfs + Snapper:
grub-mkconfigschreibt in den Snapshot, GRUB liest vom@-Subvolume. Nach jedem GRUB-Update: manuell oder per Hook synchronisieren.
Der zweite Bug ist der gemeine — er macht den ersten unsichtbar. Wer keinen Snapshot-basierten Btrfs-Setup hat, wird das nie sehen. Wer ihn hat, versteht nicht, warum seine Kernel-Parameter einfach ignoriert werden.
Kommentar schreiben