-
-
Notifications
You must be signed in to change notification settings - Fork 6
Linux Troubleshooting
When troubleshooting unexpected behavior in ZenTune, review the background daemon journal logs first. The daemon logs every preset change, privilege transition, hardware capability probe, and SMU communication attempt.
Because the daemon runs under systemd as a simple service, inspect output via journalctl:
journalctl -u zentune.service -n 100 --no-pagerTo follow live operational events:
journalctl -u zentune.service -fEvery preset execution logs its originating trigger and parameter receipt:
Applied preset 'Eco' (power source changed from AC to battery).
Applied preset 'Gaming' (selected in the app).
Applied preset 'Balanced' (restoring saved settings at startup).
For detailed debug tracing (including sysfs writes, Polkit command strings, and raw SMU arguments), configure debug = 1 in config.ini:
# /opt/zentune/src/Assets/config.ini
[Settings]
debug = 1Apply the updated configuration by restarting the service:
sudo systemctl restart zentune.service
# Or with run0:
run0 systemctl restart zentune.serviceZenTune supports two elevation backends on Linux: standard sudo and systemd run0 (backed by Polkit). Misconfigurations in elevation tooling prevent service registration, custom preset execution, and venv maintenance.
When configured to use run0, ZenTune executes commands via:
run0 --background= --pipe <command>-
Cancellation keywords: If an authorization prompt is closed, denied, or dismissed, ZenTune parses stdout and stderr for rejection tokens (
cancel,denied,not authorized,dismiss,closed). ZenTune flagswas_auth_cancelled() = Trueand gracefully halts without raising unhandled exceptions. -
Missing authentication agent: In minimal desktop environments or standalone window managers / Wayland compositors (Hyprland, Sway, i3, bspwm, dwm, river), a Polkit authentication agent is often absent from the user session. When no agent is active,
run0cannot display an interactive password prompt and immediately rejects the authorization request.
Remediation:
- Install and start a graphical Polkit agent in your window manager startup configuration:
- GNOME / Wayland:
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 - LXQt / Lightweight:
lxpolkit & - MATE:
/usr/lib/mate-polkit/mate-polkit & - KDE Plasma:
/usr/lib/polkit-kde-authentication-agent-1 &
- GNOME / Wayland:
- Alternatively, switch ZenTune to
sudo:- Within the TUI: Open Settings (
7) -> Privilege escalation tool -> choosesudo. - Manually via config: Edit
/opt/zentune/src/Assets/config.ini:[Settings] privilegetool = sudo
- Within the TUI: Open Settings (
When PrivilegeTool = sudo, ZenTune displays SudoModal to capture credentials, running sudo -S -p "" -v in a worker thread.
- If the password fails, ZenTune checks for
incorrect,denied, orpasswordin output and signals credential rejection. - If your account lacks entries in
/etc/sudoersor thesudogroup (orwheelgroup on RHEL/Fedora/Arch), userun0or add your user to the administrative group:sudo usermod -aG wheel "$USER" # Fedora / Arch sudo usermod -aG sudo "$USER" # Debian / Ubuntu
ZenTune coordinates with Linux kernel power scaling subsystems. It does not blindly write sysfs nodes when active platform daemons are managing hardware state.
platformctl.py evaluates power profile backends using a strict priority ladder:
-
Priority 1:
ppd(power-profiles-daemon)- Verified via
powerprofilesctl get,systemctl is-active --quiet power-profiles-daemon, or D-Bus query tonet.hadess.PowerProfilesviabusctl. - Profiles mapped:
power-saver,balanced,performance.
- Verified via
-
Priority 2:
tuned(TuneD)- Verified via
tuned-adm activeconfirmingCurrent active profile:. - Profiles mapped:
powersave,balanced,throughput-performance.
- Verified via
-
Priority 3:
sysfs(Direct ACPIplatform_profile)- Verified via existence of
/sys/firmware/acpi/platform_profile. - Profiles mapped:
low-power,balanced,performance.
- Verified via existence of
-
Fallback:
none- Neither daemons nor kernel ACPI platform profile nodes exist.
Detection logic and conflict arbitration: In platformctl.py, get_power_profile_backend() evaluates is_tuned_active() first; if TuneD is active, tuned is selected. The is_ppd_active() check yields (return False) when TuneD is running to prevent race conditions with TuneD's D-Bus emulation interface. When TuneD is not active, ZenTune routes profile commands through native ppd. Direct ACPI sysfs writes are used only on systems where neither daemon is running.
Why this order matters: Daemons such as power-profiles-daemon and TuneD maintain internal state machines linked to desktop environments (GNOME/KDE) or system tuning profiles. If ZenTune wrote directly to /sys/firmware/acpi/platform_profile while a daemon was managing hardware state, the daemon would detect external modification and overwrite the profile. ZenTune therefore coordinates through the active platform daemon first, using direct ACPI sysfs only on systems where no daemon is active.
Hardware embedded controllers require time to negotiate power limits and clock states:
-
Power profile settling delay: A mandatory 500 ms delay (
0.5s) is enforced after every profile change acrossppd,tuned, and rawsysfs. This blocks race conditions between profile selection and subsequent SMU limit adjustments. -
PPD performance fallback: If
performanceis rejected byppd(for example, on battery power on firmware that disallows performance mode while discharging), ZenTune falls back tobalancedand waits an additional 500 ms. -
ASUS dGPU rescan delay: When re-enabling an ASUS discrete GPU (
set_asus_eco(0)), a 50 ms settling delay occurs before writing1to/sys/bus/pci/rescan. -
Post-suspend stabilization delay: In
loops.py,_POST_SUSPEND_WAIT_S = 5.0enforces a 5.0-second pause after system resume before reapplying profiles. A 3.0-second cooldown rate-limits SMU profile applications.
If TLP is installed, it periodically enforces platform profiles on AC/battery events:
- ZenTune scans
/etc/tlp.confand/etc/tlp.d/*.conffor active keys:PLATFORM_PROFILE_ON_ACandPLATFORM_PROFILE_ON_BAT. - When present, ZenTune issues a warning receipt:
[!] TLP sets PLATFORM_PROFILE_ON_AC/BAT and will override this on power changes. Comment those out in /etc/tlp.conf to let ZenTune manage it -
Remediation: Open
/etc/tlp.confin an editor, comment out those two directives with a#, and restart TLP (sudo systemctl restart tlp).
ZenTune manages CPU Energy Performance Preference across all available cores:
- Sysfs targets:
/sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference(or/sys/devices/system/cpu/cpufreq/policy*/energy_performance_preference). - Values:
power,balance_power,balance_performance,performance. -
Driver requirement: EPP requires the
amd-pstate-eppdriver (oramd-pstatein active mode). If the legacyacpi-cpufreqdriver is loaded, EPP nodes are absent from/sys. - Inspect active driver:
If
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
acpi-cpufreqis active, addamd_pstate=activeto your kernel boot parameters in/etc/default/grubto enable EPP nodes.
ZenTune toggles processor boost via /sys/devices/system/cpu/cpufreq/boost:
- Value
1: Boost enabled. - Value
0: Boost disabled (locks frequencies to base clock ceiling). - If this sysfs file does not exist, your loaded kernel governor does not support global boost arbitration.
ZenTune integrates with asus-nb-wmi and asus-armoury sysfs trees on supported ASUS gaming laptops (ROG / TUF / Zephyrus / Flow).
Controls fan curves and acoustic/thermal profiles via:
-
/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy(or/sys/class/firmware-attributes/asus-armoury/attributes/throttle_thermal_policy/current_value). - Values: Silent =
2, Balanced =0, Turbo =1.
Eco mode cuts power to the discrete graphics processor. ZenTune enforces two critical safety refusals:
-
Refusal: Active dGPU DRM driver
- ZenTune inspects
/sys/module/nvidia_drm/refcnt. If refcnt > 0 (indicating active Xorg or Wayland client references), ZenTune refuses the operation. - For AMD dGPUs, ZenTune verifies that the discrete PCI device is bound to
amdgpuand suspended (runtime_status == "suspended"). If active, the operation is refused. - Reason: Disabling a graphics card while display server buffers or compute processes are mapped causes immediate kernel crashes or desktop freezes.
- ZenTune inspects
-
Refusal: MUX in Ultimate mode
- If the hardware display multiplexer is set to Ultimate mode (
gpu_mux_mode == 0), the internal display panel is wired directly to the dGPU. Disabling the dGPU in Ultimate mode results in an immediate black screen. - ZenTune halts and returns a refusal message until MUX is set to Optimus/Hybrid mode and the machine is rebooted.
- If the hardware display multiplexer is set to Ultimate mode (
- Values:
0= dGPU (Ultimate),1= Optimus (Hybrid). -
Refusal: dGPU disabled in Eco mode: ZenTune refuses to enable Ultimate mode if
dgpu_disable == 1. The dGPU must be powered on before switching MUX routing. -
Reboot required: Setting MUX modes does not take effect immediately; ZenTune appends
[!] reboot required to take effect.
On multi-CCD desktop processors (Ryzen 9 7900X, 7950X, 7950X3D, 9900X, 9950X), ZenTune manages task placement across L3 cache complexes:
- Target nodes:
/sys/devices/system/cpu/cpu*/cache/index3/shared_cpu_list. - Requires at least two distinct L3 cache domains and
systemctl. -
Runtime execution: Runs
systemctl set-property --runtime user.slice AllowedCPUs=<cpus>. - Selection modes:
-
0: All Cores (restores full CPU mask from/sys/devices/system/cpu/present). -
1: CCD1 Only (constrainsuser.slicetasks to the first L3 cache complex, advantageous for gaming on 7950X3D). -
2: CCD2 Only (constrains tasks to high-frequency non-V-Cache CCD).
-
If the TUI reports Daemon: Not running:
- Check systemd unit status:
systemctl status zentune.service
- Confirm IPC socket existence and permissions:
The socket permissions must be mode
ls -l /run/zentune.sock
0o666(srw-rw-rw-). - Recovering from stale locks or uncleaned sockets:
If the daemon was forcefully killed (
SIGKILL), the lock file or socket may block restart:sudo rm -f /run/zentune.sock /run/zentune_daemon.lock sudo systemctl restart zentune.service # Or with run0: # run0 rm -f /run/zentune.sock /run/zentune_daemon.lock # run0 systemctl restart zentune.service
zentune.service specifies Restart=on-failure with RestartSec=5. To isolate crash causes without continuous restarts, stop the service and execute the daemon directly in a terminal:
sudo systemctl stop zentune.service
sudo /opt/zentune/venv/bin/python3 /opt/zentune/src/Assets/daemon/daemon.py
# Or with run0:
# run0 /opt/zentune/venv/bin/python3 /opt/zentune/src/Assets/daemon/daemon.pyWhen Secure Boot is active, presets fail to apply if ryzen_smu is missing or unverified.
Install DKMS packages and compile ryzen_smu following Linux Installation §2.
Confirm module visibility:
lsmod | grep ryzen_smuVerify driver version:
cat /sys/kernel/ryzen_smu_drv/drv_versionIf older than 0.1.7, pull the latest upstream source, execute sudo make dkms-install, and reload the driver:
sudo modprobe -r ryzen_smu && sudo modprobe ryzen_smuIf modprobe fails with Key was rejected by service or Operation not permitted:
- The DKMS signing key was not imported into UEFI MOK.
- Enroll the certificate:
sudo mokutil --import /var/lib/dkms/mok.pub sudo reboot
- Complete key authorization at the blue Shim MOK screen during boot.
If power limits revert shortly after application, another background utility (such as thermald, power-profiles-daemon, or an OEM EC daemon) is overriding the SMU registers.
- Enable periodic reapplication: Open Settings (
7) -> enable Reapply preset periodically -> set interval to3seconds.
Hardware SMU registers clear during deep sleep (S3 or S0ix modern standby).
- Navigate to Automations (
4) -> Preset on System Resume -> select your target profile. - ZenTune detects resume by comparing monotonic clock progression against real-time clock advance, waiting
5.0seconds (_POST_SUSPEND_WAIT_S) before issuing SMU commands to let firmware settle.
When reporting issues to the development tracker, collect the following diagnostics:
# Distribution and kernel
uname -a
cat /etc/os-release
# Python and virtual environment status
python3 --version
/opt/zentune/venv/bin/python3 --version
# Privilege tool and backend status
which sudo run0 2>/dev/null
powerprofilesctl get 2>/dev/null || tuned-adm active 2>/dev/null || cat /sys/firmware/acpi/platform_profile 2>/dev/null
# Hardware identification
cat /sys/kernel/ryzen_smu_drv/drv_version 2>/dev/null || echo "ryzen_smu not loaded"
grep -E "^cpu family|^model|^model name" /proc/cpuinfo | head -6
# Recent daemon journal receipts
journalctl -u zentune.service -n 40 --no-pagerGetting started
Using the app
Internals