From 2015d4c96e757a5c48a88d1079f13db17244a3ed Mon Sep 17 00:00:00 2001 From: Christian Werner Date: Mon, 22 Jun 2026 00:09:50 +0200 Subject: [PATCH] docs(kernel): document DATA line locking design to prevent RMW collisions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add row to "Decisions baked into the code" table explaining the DATA line control design: all DATA assert/release operations in the worker and ATN ISR go through iec_data_*_sync() under iec_data_lock to serialize the GPFSEL0 read-modify-write across CPUs. The release wrapper refuses to release while ATN is asserted, preventing the ready-for-data release from erasing the ISR's presence acknowledge — the bug that caused intermittently missed LISTEN/UNLISTEN commands. Init/exit/self-test keep raw unconditional helpers. Generated by Clanker 🤖 --- docs/kernel-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/kernel-notes.md b/docs/kernel-notes.md index a70b95f..f9444ae 100644 --- a/docs/kernel-notes.md +++ b/docs/kernel-notes.md @@ -16,6 +16,7 @@ the code in `kernel/` is built on. | Kernel↔userspace | Character device `/dev/iec0` + `kfifo` + wait queue (IEC ≤ 1000 B/s; relayfs not justified) | `iec_read`, `emit_record` | | `udelay` vs. poll | Poll-with-timeout for CLK transitions; `udelay` only for fixed delays (EOI ack 80 µs, EOI detect 250 µs) | `iec_timing.h`, `wait_clk` | | Sense-line reads | Debounced (glitch-filtered): a level change is believed only after it holds `IEC_DEBOUNCE_US` (5 µs); shorter pulses are rejected as noise. Mirrors a confirmed-working reference listener. Fast path is a single register read, so tight CLK polls stay cheap. ATN ISR + self-test stay **raw** | `iec_read_stable`, `db_*_asserted` | +| DATA line control | All DATA assert/release in the worker + ATN ISR go through `iec_data_*_sync()` under `iec_data_lock`. The pin direction-flip is a read-modify-write of the shared `GPFSEL0`; without the lock the worker (one CPU) and the ATN ISR (another CPU on the quad-core Pi) could clobber each other's RMW. The release wrapper also **refuses to release while ATN is asserted**, so a ready-for-data release can never erase the ISR's presence acknowledge — the bug that caused intermittently missed LISTEN/UNLISTEN commands. init/exit/self-test keep the **raw** unconditional helpers | `iec_data_assert_sync`, `iec_data_release_sync`, `atn_isr` | | isolcpus / nohz_full | **Not** in the Phase-1 baseline. Add `isolcpus=3 nohz_full=3 rcu_nocbs=3 irqaffinity=0-2` only if Phase-2 bit-error rate > 1% | (boot cmdline) | | PREEMPT_RT | Stock kernel sufficient; RT is a last resort | — | | Module signing | Not required on stock RPi OS Bookworm | — |