Files
kde-cpufreq-dashboard/README.md
T
enne2 d4902b0b72 Plasmoide CPU Frequency Control: governor, limiti, EPP, boost e profili per task
Widget KDE Plasma 6 (org.enne2.cpufreq) per pilotare il profilo energetico della
CPU: governor, limiti min/max, energy_performance_preference, boost/turbo,
quattro profili pronti (Silenzioso, Risparmio, Bilanciato, Performance) e task
con profilo dedicato che ripristina lo stato precedente alla fine del comando.

Privilegi separati: il widget resta non privilegiato e l'unica operazione root
passa da un helper a interfaccia ristretta in /usr/local/libexec/enne2-cpufreq/
(comandi a elenco chiuso, argomenti validati su sysfs, rilettura di verifica),
invocato via pkexec con l'azione polkit dedicata org.enne2.cpufreq.set. La regola
in /etc/polkit-1/rules.d/ concede il consenso senza prompt a utenti locali in
sessione attiva nel gruppo wheel; senza la regola la policy chiede la password.

Dettagli verificati su frigate (Plasma 6.7.5, kernel 7.2, amd-pstate-epp):
- con boost disattivato cpuinfo_max_freq scende alla frequenza nominale, quindi
  il tetto hardware si legge da amd_pstate_max_freq e i profili applicano il
  boost prima dei limiti;
- scrittura dei limiti in ordine sicuro (mai min > max intermedio);
- baseline e contatore di riferimento per i task paralleli;
- syncControls protetto da uiReady e try/catch: un ReferenceError su un id della
  rappresentazione non deve interrompere l'aggiornamento dello stato;
- implicitWidth/Height costanti, altrimenti il containment riduce il widget a
  68x68.

Include install.sh/uninstall.sh (widget, backend, dry-run), README con modello di
sicurezza e diagnostica, screenshot docs/widget.png. Licenza MIT.
2026-10-25 20:42:52 +01:00

164 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](docs/widget.png)
## 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
```sh
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:
```js
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:
```sh
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
```sh
/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.