* [PATCH v2 1/2] spi: unoptimize message when queuing it fails
[not found] <20261103224753.3610049-1-jctchan@gmail.com>
@ 2026-11-03 22:47 ` Joseph CT Chan
0 siblings, 0 replies; only message in thread
From: Joseph CT Chan @ 2026-11-03 22:47 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi, David Lechner, Bart Van Assche, Joseph CT Chan, stable
From: Joseph CT Chan <josephctchan@google.com>
spi_async() and spi_sync() optimize a message before they queue it.
When queuing then fails, the message is never finalized, but finalizing
is the only place where the core undoes its own optimization
(spi_finalize_current_message() calls spi_maybe_unoptimize_message()).
So the error paths leak the split transfers and the controller's
optimize state, and leave msg->optimized set. A caller that resends the
message then optimizes an already optimized message.
This happens when spi_async() returns -EBUSY because another device
holds spi_bus_lock() on the controller (for example mmc_spi), when the
controller's message queue is stopped (-ESHUTDOWN), when the controller
has no ->transfer() callback (-ENOTSUPP), and when __spi_sync() gets an
error from a controller's legacy ->transfer() callback.
Call spi_maybe_unoptimize_message() on these two error paths. It only
acts on messages the core optimized itself, so messages optimized by
the peripheral driver and controllers that defer optimization (such as
spi-mux) are not affected. A queued message is never unoptimized here.
Tested with KUnit (spi_core_optimize: spi_core_queue_error_test,
added later in this series) on ARCH=um; builds with W=1 on x86_64.
Not tested on hardware.
Developed with help from the Claude and Gemini AI assistants.
Fixes: 7b1d87af14d9 ("spi: add spi_optimize_message() APIs")
Fixes: c86a918b1bdb ("spi: don't unoptimize message in spi_async()")
Cc: stable@vger.kernel.org
Signed-off-by: Joseph CT Chan <josephctchan@google.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
---
v2: Added Reviewed-by from David Lechner.
drivers/spi/spi.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 40cda0037ea5..0d36460e2c87 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -4906,6 +4906,10 @@ int spi_async(struct spi_device *spi, struct spi_message *message)
spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags);
+ /* The message was not queued, so it will not be finalized. */
+ if (ret)
+ spi_maybe_unoptimize_message(message);
+
return ret;
}
EXPORT_SYMBOL_GPL(spi_async);
@@ -5009,6 +5013,9 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
if (status == 0) {
wait_for_completion(&done);
status = message->status;
+ } else {
+ /* The message was not queued, so it will not be finalized. */
+ spi_maybe_unoptimize_message(message);
}
message->complete = NULL;
message->context = NULL;
--
2.56.0.385.gac671c819a-goog
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-11-03 22:48 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20261103224753.3610049-1-jctchan@gmail.com>
2026-11-03 22:47 ` [PATCH v2 1/2] spi: unoptimize message when queuing it fails Joseph CT Chan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox