Problem
Ziel: Lüfterkurve der Radeon RX 7900 XT (RDNA3) unter CachyOS/Arch Linux temperaturgesteuert über ein Python-Script regeln. Ruhiger Betrieb im Leerlauf, aggressives Kühlen bei Last.
Fehlerbild
Der klassische hwmon-Weg (/sys/class/hwmon/hwmon2/pwm1) schlug vollständig fehl:
pwm1_enable = 1(manual) schreiben → Write OK, aber sofort zurück auf2pwm1schreiben →EINVAL(weil enable=2 = Auto)fan1_target→ENODATAfan1_enable→ springt zurück auf 0power_dpm_force_performance_level=manual→ Write OK, liest sofortautozurückrocm-smi --setfan→ „Not supported on the given system“
Analyse
Die RX 7900 XT nutzt den AMD SMU 13.0.4 (Navi31, RDNA3). Das pp_features-Interface zeigt Bit 30 als FAN_CONTROL: enabled. Versuche, dieses Feature zur Laufzeit zu deaktivieren (echo "30 0" > pp_features), scheiterten mit EINVAL.
Ursache: Der SMU-Firmware-Chip auf RDNA3-Karten übernimmt nach GPU-Init die vollständige autonome Steuerung von pwm1_enable. Jeder Schreibversuch auf den Standard-hwmon-Pfad wird von der Firmware sofort rückgängig gemacht.
Lösungsweg
Die Lösung ist das OverDrive-Interface (gpu_od), das speziell für RDNA3 im amdgpu-Treiber implementiert ist:
/sys/devices/pci.../gpu_od/fan_ctrl/fan_curve
/sys/devices/pci.../gpu_od/fan_ctrl/fan_zero_rpm_enable
/sys/devices/pci.../gpu_od/fan_ctrl/fan_minimum_pwm
/sys/devices/pci.../pp_od_clk_voltage ← commit mit "c"
Über dieses Interface programmiert man eine 5-Punkte-Kurve direkt in die SMU-Firmware. Die Firmware übernimmt die Kurve und regelt den Lüfter anhand der Hotspot-Temperatur selbstständig — korrekt, stabil, ohne Konflikte mit dem Kernel.
Änderungen & Fix
fancurve.service (/usr/local/bin/fancurve, Python-Daemon):
- Schreibt beim Start die 5-Punkte-Kurve in
gpu_od/fan_ctrlund committed - Überwacht alle 30 s ob die Kurve noch aktiv ist (nach Resume/Driver-Reset)
- Stellt beim Stopp die Firmware-Standardkurve wieder her (
echo "r" > pp_od_clk_voltage)
Kurve (Hotspot °C → Lüfter-Duty %):
30°C → 23% 55°C → 23% 72°C → 45% 83°C → 65% 95°C → 90%
fanmon (/usr/local/bin/fanmon) — interaktives TUI-Script:
- Zeigt alle Sensoren: GPU (Junction/Edge/Memory/Fan), CPU (k10temp), Gehäuse-Lüfter (nct6687), NVMe
- Live-Balken mit Farbkodierung (grün/gelb/rot)
- Kurven-Editor: Taste e → Punkte per Pfeil-/Zifferntasten anpassen → Enter speichert direkt in Firmware + patcht Daemon
Überlebt Updates?
| Was | Sicher? | Grund |
|---|---|---|
| Paket-Updates (pacman) | ✅ Ja | /usr/local/bin/ und /etc/systemd/system/ nicht unter pacman |
| Kernel-Update minor | ✅ Ja | gpu_od-Interface stabil seit amdgpu ≥ 6.6 |
| Reboot / Suspend-Resume | ✅ Ja | fancurve.service re-applyed automatisch |
| coolercontrol-Update | ⚠️ Prüfen | config.toml könnte überschrieben werden → amdgpu ggf. neu deaktivieren |
| Kernel Major / amdgpu-Pfad-Änderung | ⚠️ Selten | GPU_DEV-Pfad in fancurve.py und fanmon.py ggf. anpassen |
Fazit
Der Standard-hwmon-Weg funktioniert bei RDNA3 grundsätzlich nicht — der SMU 13.0.4 verhindert das auf Firmware-Ebene. Die korrekte Methode ist gpu_od/fan_ctrl (OverDrive-Interface), das eine direkte Programmierung der Firmware-Kurve erlaubt. Einmal gesetzt, steuert die Firmware den Lüfter selbst nach der eigenen Kurve — stabil, ohne dauernde Schreibversuche vom Host.
⬇ Downloads
Alle Dateien für diesen Post — direkt einsatzbereit auf CachyOS / Arch Linux.
sudo install -m755 fancurve.py /usr/local/bin/fancurve && sudo install -m644 fancurve.service /etc/systemd/system/ && sudo systemctl enable --now fancurve