CPU Frequency Control (org.enne2.cpufreq)

Plasmoide KDE Plasma 6 per pilotare il profilo energetico della CPU: governor, limiti di frequenza (min/max), energy_performance_preference (EPP), boost/turbo, quattro profili pronti e task con profilo dedicato che ripristina lo stato precedente quando il comando finisce.

Verificato su frigate (Fedora 44, Plasma 6.7.5 Wayland, kernel 7.2, AMD Ryzen 7 H 255, driver amd-pstate-epp in modalità active, 16 policy).

widget

Cosa fa

Area Azione
Profili Silenzioso (EPP power, boost off, tetto 35%), Risparmio (balance_power, boost off, tetto 60%), Bilanciato (balance_performance, boost on, nessun tetto), Performance (governor performance, EPP performance, boost on)
Governor pillole con i valori realmente disponibili in scaling_available_governors
EPP pillole con i valori di energy_performance_available_preferences
Limiti due slider min/max in kHz con validazione e rilettura; il valore applicato è arrotondato a 10 MHz
Boost pillole on/off (per-policy su kernel recenti, altrimenti globale, altrimenti intel_pstate/no_turbo)
Task elenco configurabile: ogni task applica un profilo, esegue il comando come utente e ripristina la baseline all'uscita
Footer messaggio dell'ultima azione e pulsante Reset (default hardware: boost on, nessun tetto)

La vista compatta (pannello) mostra frequenza corrente e un badge no boost. La frequenza è la massima fra le policy (core più attivo), con la media sotto.

Architettura e modello di sicurezza

org.enne2.cpufreq (QML, non privilegiato)
  ├─ contents/scripts/cpufreq-state.sh      lettura sysfs, /proc, hwmon   (nessun privilegio)
  ├─ contents/scripts/enne2-cpufreq-task    launcher task                 (utente)
  └─ pkexec /usr/local/libexec/enne2-cpufreq/cpufreq-helper   (root)
        ├─ comandi a elenco chiuso, argomenti validati contro sysfs
        ├─ ogni scrittura riletta per verifica
        └─ /var/lib/enne2-cpufreq/{baseline,refcount}  (root:root 0755/0644)

polkit
  ├─ /usr/share/polkit-1/actions/org.enne2.cpufreq.set.policy   azione dedicata
  └─ /etc/polkit-1/rules.d/50-org.enne2.cpufreq.rules           allow senza prompt
  • Il widget non è mai root: l'unica operazione privilegiata è l'helper, con sottocomandi fissi (set-governor, set-epp, set-limits, set-boost, apply, reset, task-begin, task-end, save-state, restore-state).
  • L'annotazione org.freedesktop.policykit.exec.path lega l'azione polkit a quel solo binario: nessun altro programma eredita il permesso.
  • La regola in /etc/polkit-1/rules.d/ concede polkit.Result.YES solo a utenti locali, con sessione attiva, nel gruppo wheel. Senza quel file la .policy chiede la password a ogni modifica (auth_admin_keep).
  • I comandi dei task girano come utente (setsid sh -c), mai come root.

Installazione

cd ~/Dev/kde-cpufreq-dashboard
./install.sh                    # widget (utente) + backend (sudo)
./install.sh --widget           # solo il plasmoide
./install.sh --backend          # solo helper + polkit (root)
./install.sh --no-polkit-rule   # backend senza la regola "nessun prompt"
./install.sh --dry-run          # mostra le operazioni

Il widget si aggiunge da Aggiungi widget → «CPU Frequency Control» oppure via scripting Plasma:

desktops()[0].addWidget("org.enne2.cpufreq")

Disinstallazione: ./uninstall.sh (ripristina la baseline prima di rimuovere l'helper). I task configurati restano in ~/.config/enne2-cpufreq/tasks.json.

Task con profilo dedicato

Dall'interfaccia: Nuovo → nome, comando, profilo. Da terminale:

enne2-cpufreq-task list
enne2-cpufreq-task add "Render Blender" performance "blender -b scena.blend -f 1"
enne2-cpufreq-task run  render-blender
enne2-cpufreq-task stop render-blender
enne2-cpufreq-task active

Sequenza di run:

  1. helper task-begin <profilo>: salva la baseline (solo al primo task) e applica il profilo
  2. il comando parte staccato (setsid) e scrive il proprio pid in $XDG_RUNTIME_DIR/enne2-cpufreq/<slug>.pid
  3. un watcher attende l'uscita del pid e chiama helper task-end, che decrementa un contatore e ripristina la baseline a zero (con notify-send di conferma)

Più task in parallelo sono contati: il ripristino avviene solo quando l'ultimo termina. enne2-cpufreq-task remove rifiuta di rimuovere un task in esecuzione.

Comportamento sui driver

  • amd-pstate-epp (active): powersave/performance sono policy del driver; powersave non blocca la frequenza al minimo, EPP è il vero bias. Con boost=0 il kernel abbassa cpuinfo_max_freq alla frequenza nominale (3.80 GHz invece di 4.97 GHz): il tetto reale viene letto da amd_pstate_max_freq, e per questo apply imposta prima il boost e poi i limiti.
  • intel_pstate: boost tramite intel_pstate/no_turbo (invertito).
  • Altri driver cpufreq: governor e limiti restano validi; EPP e boost compaiono solo se le interfacce esistono.

Servizi concorrenti

Se tuned, power-profiles-daemon o tlp sono attivi il widget lo segnala: il profilo balanced di tuned scrive esattamente governor, energy_performance_preference e boost, quindi un tuned-adm profile o il boot possono sovrascrivere le impostazioni. Su frigate tuned è attivo: le modifiche valgono fino al prossimo apply di tuned.

Diagnosi

/usr/local/libexec/enne2-cpufreq/cpufreq-helper status      # stato, baseline, refcount
~/.local/share/plasma/plasmoids/org.enne2.cpufreq/contents/scripts/cpufreq-state.sh
pkexec /usr/local/libexec/enne2-cpufreq/cpufreq-helper apply balanced
journalctl --user -u plasma-plasmashell.service -f | grep cpufreq
Sintomo Causa
banner rosso «Backend non installato» manca /usr/local/libexec/enne2-cpufreq/ → ./install.sh --backend
dialog password a ogni modifica manca la regola polkit (o utente fuori da wheel)
«autorizzazione negata da polkit» regola non caricata: systemctl try-reload-or-restart polkit
valori che tornano indietro servizio concorrente (tuned/power-profiles-daemon/tlp)
il widget resta 68×68 implicitWidth/Height del plasmoide non validi: verificare main.qml

Note di implementazione Plasma 6

  • metadata.json con X-Plasma-API-Minimum-Version: "6.0", senza chiavi Plasma 5.
  • Comandi via org.kde.plasma.plasma5support (engine: "executable"); ogni azione usa un source univoco (contatore in coda) perché il motore non riesegue un source già noto.
  • syncControls() è protetto: applyState() gira ogni 2 s e la rappresentazione piena può non esistere (popup chiuso) → senza guardia il ReferenceError su un id interrompeva la sincronizzazione dei controlli.
  • implicitWidth/implicitHeight del Flickable sono costanti: se dipendono dal layout il containment riduce il widget alla dimensione minima (68×68).
  • Nessun Switch per il boost: toggled scatta anche quando il valore viene riallineato dallo stato. Le pillole sono prive di stato interno.

File

metadata.json
contents/ui/main.qml                 interfaccia (compact + full, Flickable)
contents/ui/ChoicePill.qml           pillola selezionabile
contents/scripts/profiles.sh         tabella profili condivisa (unica fonte)
contents/scripts/cpufreq-state.sh    lettura stato non privilegiata
contents/scripts/enne2-cpufreq-task  launcher task (utente)
bin/cpufreq-helper                   helper privilegiato (root)
polkit/*.policy, polkit/*.rules      azione e regola polkit
install.sh, uninstall.sh

Licenza MIT.

S
Description
Plasmoide KDE Plasma 6 per controllare profilo energetico della CPU: governor, limiti di frequenza min/max, EPP, boost/turbo, profili pronti e task con profilo dedicato e ripristino automatico. Backend: helper privilegiato via pkexec + azione polkit dedicata.
Readme MIT
570 KiB
Languages
QML 52.3%
Shell 47.7%