Skip to content

Linux Troubleshooting

Le Khanh Binh edited this page Sep 13, 2026 · 2 revisions

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.


1. Inspecting daemon journal logs

Because the daemon runs under systemd as a simple service, inspect output via journalctl:

journalctl -u zentune.service -n 100 --no-pager

To follow live operational events:

journalctl -u zentune.service -f

Every 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).

Enabling verbose debug logging

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 = 1

Apply the updated configuration by restarting the service:

sudo systemctl restart zentune.service
# Or with run0:
run0 systemctl restart zentune.service

2. Privilege elevation & Polkit troubleshooting

ZenTune 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.

2.1 Polkit authorization cancelled or prompt missing

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 flags was_auth_cancelled() = True and 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, run0 cannot display an interactive password prompt and immediately rejects the authorization request.

Remediation:

  1. 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 &
  2. Alternatively, switch ZenTune to sudo:
    • Within the TUI: Open Settings (7) -> Privilege escalation tool -> choose sudo.
    • Manually via config: Edit /opt/zentune/src/Assets/config.ini:
      [Settings]
      privilegetool = sudo

2.2 Sudo password rejection or timeout

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, or password in output and signals credential rejection.
  • If your account lacks entries in /etc/sudoers or the sudo group (or wheel group on RHEL/Fedora/Arch), use run0 or add your user to the administrative group:
    sudo usermod -aG wheel "$USER"   # Fedora / Arch
    sudo usermod -aG sudo "$USER"    # Debian / Ubuntu

3. Power profile backend prioritization & settling delays

ZenTune coordinates with Linux kernel power scaling subsystems. It does not blindly write sysfs nodes when active platform daemons are managing hardware state.

3.1 Critical backend prioritization order

platformctl.py evaluates power profile backends using a strict priority ladder:

  1. Priority 1: ppd (power-profiles-daemon)
    • Verified via powerprofilesctl get, systemctl is-active --quiet power-profiles-daemon, or D-Bus query to net.hadess.PowerProfiles via busctl.
    • Profiles mapped: power-saver, balanced, performance.
  2. Priority 2: tuned (TuneD)
    • Verified via tuned-adm active confirming Current active profile:.
    • Profiles mapped: powersave, balanced, throughput-performance.
  3. Priority 3: sysfs (Direct ACPI platform_profile)
    • Verified via existence of /sys/firmware/acpi/platform_profile.
    • Profiles mapped: low-power, balanced, performance.
  4. 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.

3.2 Settling delays

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 across ppd, tuned, and raw sysfs. This blocks race conditions between profile selection and subsequent SMU limit adjustments.
  • PPD performance fallback: If performance is rejected by ppd (for example, on battery power on firmware that disallows performance mode while discharging), ZenTune falls back to balanced and 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 writing 1 to /sys/bus/pci/rescan.
  • Post-suspend stabilization delay: In loops.py, _POST_SUSPEND_WAIT_S = 5.0 enforces a 5.0-second pause after system resume before reapplying profiles. A 3.0-second cooldown rate-limits SMU profile applications.

3.3 TLP conflict detection

If TLP is installed, it periodically enforces platform profiles on AC/battery events:

  • ZenTune scans /etc/tlp.conf and /etc/tlp.d/*.conf for active keys: PLATFORM_PROFILE_ON_AC and PLATFORM_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.conf in an editor, comment out those two directives with a #, and restart TLP (sudo systemctl restart tlp).

4. CPU Energy Performance Preference (EPP) and Boost

4.1 EPP configuration (--sys-epp)

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-epp driver (or amd-pstate in active mode). If the legacy acpi-cpufreq driver is loaded, EPP nodes are absent from /sys.
  • Inspect active driver:
    cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
    If acpi-cpufreq is active, add amd_pstate=active to your kernel boot parameters in /etc/default/grub to enable EPP nodes.

4.2 CPU Turbo Boost (--sys-cpu-boost)

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.

5. ASUS WMI platform controls & safety refusals

ZenTune integrates with asus-nb-wmi and asus-armoury sysfs trees on supported ASUS gaming laptops (ROG / TUF / Zephyrus / Flow).

5.1 Throttle Thermal Policy

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.

5.2 GPU Eco Mode refusals (dgpu_disable)

Eco mode cuts power to the discrete graphics processor. ZenTune enforces two critical safety refusals:

  1. 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 amdgpu and 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.
  2. 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.

5.3 GPU MUX Mode refusals (gpu_mux_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.

6. CCD core affinity (Dual-CCD Ryzen)

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 (constrains user.slice tasks to the first L3 cache complex, advantageous for gaming on 7950X3D).
    • 2: CCD2 Only (constrains tasks to high-frequency non-V-Cache CCD).

7. Daemon IPC socket & process management

7.1 "Not running" or IPC connection failure

If the TUI reports Daemon: Not running:

  1. Check systemd unit status:
    systemctl status zentune.service
  2. Confirm IPC socket existence and permissions:
    ls -l /run/zentune.sock
    The socket permissions must be mode 0o666 (srw-rw-rw-).
  3. 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

7.2 Service flapping / restart loops

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.py

8. ryzen_smu kernel module issues (Secure Boot only)

When Secure Boot is active, presets fail to apply if ryzen_smu is missing or unverified.

8.1 "ryzen_smu kernel module is not installed"

Install DKMS packages and compile ryzen_smu following Linux Installation §2. Confirm module visibility:

lsmod | grep ryzen_smu

8.2 Version too old (<0.1.7)

Verify driver version:

cat /sys/kernel/ryzen_smu_drv/drv_version

If 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_smu

8.3 Module verification failure on Secure Boot

If modprobe fails with Key was rejected by service or Operation not permitted:

  1. The DKMS signing key was not imported into UEFI MOK.
  2. Enroll the certificate:
    sudo mokutil --import /var/lib/dkms/mok.pub
    sudo reboot
  3. Complete key authorization at the blue Shim MOK screen during boot.

9. Preset reversion and sleep/resume

9.1 Presets reverting after several seconds

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 to 3 seconds.

9.2 Presets resetting after suspend

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.0 seconds (_POST_SUSPEND_WAIT_S) before issuing SMU commands to let firmware settle.

10. System diagnostic collection

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-pager

Clone this wiki locally