113 lines
4.9 KiB
Markdown
113 lines
4.9 KiB
Markdown
# Piano: quiescing dell'engine a shutdown (`.shutdown`)
|
|
|
|
**Contesto** (2026-07-31): ws1-mint ha un hang intermittente di poweroff (LED
|
|
acceso, tutto il resto spento), isolato al tratto `machine_power_off()` →
|
|
ACPI `_S5`. Evidenza: reboot mai appesi (5/5, anche dopo sessioni di 32 h),
|
|
Windows con Fast Startup disattivato mai appeso, journal degli shutdown appesi
|
|
byte-identici a quelli puliti, netconsole muto dopo `mlx4_shutdown`. Ipotesi di
|
|
lavoro: l'handler SMI del BIOS (ASUS TUF X299 MARK 1, BIOS 4201) al trap di S5
|
|
trova l'engine SMBus dell'iMC in stato "di sessione" e si inchioda. L'engine è
|
|
usato tutta la sessione da furyd (ENE 0x27 su entrambi i canali) e dai tool di
|
|
sviluppo.
|
|
|
|
**Questo piano è hygiene corretta a prescindere dall'esito**: il driver
|
|
condivide l'engine con il firmware (vedi commento in testa al sorgente) e oggi
|
|
non lo riconsegna mai. La conferma causale resta affidata alla console seriale
|
|
(`console=ttyS0`), piano separato.
|
|
|
|
Ordine: eseguire prima questo piano, poi il gemello in
|
|
`~/_Workspace/furyrs/docs/plans/shutdown-smbus-hygiene.md`.
|
|
|
|
---
|
|
|
|
## T1 — Snapshot pristino dei registri a probe
|
|
|
|
**GOAL**: salvare, una volta sola al bind, le CMD word di entrambi i canali
|
|
com'erano prima di qualunque transfer del driver: sono lo stato che il
|
|
firmware ha lasciato al boot e che deve ritrovare a `_S5`.
|
|
|
|
**ANCHORS**: `i2c-imc-skylake.c` — `struct imc_smbus` (r. 162),
|
|
`imc_pci_probe()` (r. 675, dopo `imc_check_firmware_polling` e prima della
|
|
registrazione degli adapter).
|
|
|
|
**CHANGE**: due nuovi campi (uno per canale) in `struct imc_smbus`, letti in
|
|
probe con l'accessor esistente. Fallimento di lettura (`io_err`) = fallire il
|
|
probe: uno snapshot inattendibile rende il quiescing dannoso.
|
|
|
|
**CONSTRAINTS**: nessun cambiamento al path dei transfer; niente scritture in
|
|
probe.
|
|
|
|
**VERIFY**: `grep -n "pristine\|boot_cmd" i2c-imc-skylake.c` mostra campo +
|
|
unico punto di scrittura in probe; smoke test invariato.
|
|
|
|
## T2 — Callback `.shutdown`
|
|
|
|
**GOAL**: a shutdown/kexec: nessun transfer in volo, engine idle, CMD word
|
|
pristine ripristinate (mascherate `~GO_BIT`). Best effort, mai bloccante oltre
|
|
i timeout esistenti, mai panic.
|
|
|
|
**ANCHORS**: `struct pci_driver imc_driver` (r. 770), `imc_suspend()` (r. 637,
|
|
modello per marcare gli adapter suspended), `mutex` `s->lock` (r. 165),
|
|
`imc_wait_engine_idle()` (r. 218), `imc_restore_xfer()` (r. 366, modello per
|
|
la scrittura mascherata).
|
|
|
|
**CHANGE**: nuova `imc_pci_shutdown(struct pci_dev *)` registrata in
|
|
`imc_driver`. Sequenza-invariante: guard su `drvdata` NULL (probe mai riuscito)
|
|
→ marca entrambi gli adapter suspended (blocca nuovi transfer) → `mutex_lock`
|
|
(drena l'eventuale transfer in volo, bounded ~750 ms worst case) → attesa
|
|
engine idle → ripristino word pristine → unlock. Errori di config space:
|
|
ignorati (a shutdown non c'è nessuno a cui riportarli), ma niente scritture se
|
|
la lettura dello snapshot in probe era fallita (non accade: T1 fallisce il
|
|
probe).
|
|
|
|
**CONSTRAINTS**: nessuna allocazione, nessun sleep oltre i poll esistenti;
|
|
callback idempotente; vale anche per kexec (stesso callback, stessa
|
|
correttezza).
|
|
|
|
**VERIFY**: build DKMS pulita per il kernel corrente;
|
|
`grep -n "\.shutdown" i2c-imc-skylake.c` → registrata; con `dev_dbg` attivo un
|
|
reboot mostra la callback eseguita (`journalctl -k -b -1` dopo reboot con
|
|
`dyndbg` sul modulo).
|
|
|
|
## T3 — Snapshot rinfrescato al resume
|
|
|
|
**GOAL**: dopo S3 il firmware può aver usato l'engine (osservato: read SPD in
|
|
memory training al resume) → lo snapshot di probe è potenzialmente stantio.
|
|
|
|
**ANCHORS**: `imc_resume()` (r. 648).
|
|
|
|
**CHANGE**: se il re-check `imc_check_firmware_polling` passa, ri-leggere le
|
|
CMD word e aggiornare lo snapshot prima di rimarcare gli adapter resumed. Se
|
|
la lettura fallisce: adapter restano suspended (comportamento attuale sul
|
|
fallimento del re-check).
|
|
|
|
**VERIFY**: suspend/resume manuale (`test-suspend.sh`) invariato; snapshot
|
|
aggiornato osservabile via `dev_dbg`.
|
|
|
|
## T4 — Commento di lifetime da correggere
|
|
|
|
**GOAL**: il blocco "register state deliberately left as-is on unbind"
|
|
(r. 762-769) resta vero per l'unbind a OS vivo ma diventa falso come rationale
|
|
globale: a shutdown il prossimo utente è il firmware.
|
|
|
|
**CHANGE**: riscrivere il commento distinguendo unbind (as-is, corretto) da
|
|
shutdown (handback pristino, T2). È materiale utile anche per il cover letter
|
|
v3: engine firmware-shared + caso reale di wedge S5 sotto indagine.
|
|
|
|
**VERIFY**: il commento nomina entrambe le semantiche; `checkpatch.pl --strict`
|
|
pulito sul diff complessivo.
|
|
|
|
## T5 — Versioning
|
|
|
|
**CHANGE**: bump `VERSION` e `dkms.conf` (1.0.4); nota in `TODO.md` che il
|
|
quiescing è in test come possibile fix dell'hang S5 (link a questo file).
|
|
|
|
**VERIFY**: `dkms status` mostra la nuova versione installata per il kernel
|
|
corrente; `test-smoke.sh` verde end-to-end.
|
|
|
|
---
|
|
|
|
**Fuori scope qui**: qualunque modifica a furyd (piano gemello), la console
|
|
seriale, i tool `probe-cf8-*` (restano strumenti di indagine, non li tocca
|
|
questo piano).
|