diff options
| author | Mark Brown <broonie@kernel.org> | 2026-09-09 12:48:32 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-09-09 12:48:32 +0100 |
| commit | b34afbedb11c417598eeab9e326d8010bdcc423c (patch) | |
| tree | 45c57e2b74d7c4c3e9a13b8da9cd5f7c30cc346d /tools/perf/scripts/python/bin | |
| parent | e95dac34dd5763c125dc597a159d72922b4f8fbb (diff) | |
| parent | 252ee24aff97cd0a14c192c200753487ed88ee24 (diff) | |
spi: tegra210-quad: Improve interrupt handling for loaded systems
Vishwaroop A <va@nvidia.com> says:
The current threaded IRQ implementation in spi-tegra210-quad suffers
from scheduler-induced latency on heavily loaded systems. The old
irq_thread() runs SCHED_FIFO but is pinned by the kernel to the IRQ
affinity mask (typically one CPU); when that CPU is saturated by RT
workloads (e.g. NCCL multicast) or by an SPI transaction coming from
a higher-priority context, the sleeping DMA/PIO wait inside the IRQ
thread cannot progress and wait_for_completion_timeout() in
transfer_one_message expires - even though the QSPI hardware
finished on time. This results in false timeout errors and WARN_ON
splats during normal operation.
This series addresses the problem in three steps:
1. Convert the threaded IRQ handler to a hard IRQ + high-priority
unbound workqueue model. The hard IRQ does the minimum: capture
FIFO status, mask and clear the controller IRQ, then schedule the
bottom half. The workqueue handler runs in process context (can
sleep for DMA completion) and runs on any CPU in the WQ_UNBOUND
pool, so the bottom half can migrate off the interrupt-taking CPU
that the previous threaded IRQ pinned to via
set_cpus_allowed_ptr(irq_affinity).
2. Cache QSPI_TRANS_STATUS in the ISR before clearing it. This lets
the timeout handler distinguish between a real hardware timeout
(QSPI_RDY not set) and a delayed workqueue (QSPI_RDY set),
preventing false timeout errors when hardware has already
completed. Pair the cache publication with
smp_store_release()/smp_load_acquire() so the timeout handler
observes a coherent set of cached fields on weakly-ordered
architectures. In v6 the timeout handler is additionally serialised
with the workqueue via cancel_work_sync() and only runs the manual
completion fallback on the last chunk of a transfer (see "Changes
since v5" below for the multi-chunk DMA race Mark identified).
3. Process small PIO transfers (those that complete the whole
spi_transfer in a single chunk) directly in hard IRQ context,
eliminating workqueue scheduling latency for TPM-style short reads.
Runtime PM lifetime note (unchanged from v4): the work handler only
touches QSPI MMIO when curr_xfer is non-NULL. While curr_xfer is set,
the transfer thread is blocked in wait_for_completion_timeout() with
the SPI core's runtime PM reference held, so the clocks are
guaranteed on. When the work handler runs late after the timeout path
has already processed the transfer, it sees curr_xfer == NULL and
returns without any MMIO. With this invariant no additional PM
reference handoff between the ISR and the work handler is needed.
Link: https://patch.msgid.link/20260813200027.2711863-1-va@nvidia.com
Diffstat (limited to 'tools/perf/scripts/python/bin')
0 files changed, 0 insertions, 0 deletions
