Files
i2c-imc-skylake/docs/shutdown-quiescing-plan.md
T

4.9 KiB

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