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.
164 lines
7.6 KiB
Markdown
164 lines
7.6 KiB
Markdown
# 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).
|
||
|
||

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