Re: [RFC] spi: handling a stuck queue worker during controller unregister
From: Yaohan Li
Date: Fri Nov 13 2026 - 21:18:03 EST
Hi Mark,
Thanks for offering to review a patch.
I tried a core-side fix for the unregister race, but found that the lifetime
rules need more thought before the patch is ready.
The original problem is that spi_destroy_queue() can time out while the pump
worker is still running. Unregister then continues, potentially releasing the
controller while the worker is still using it.
I experimented with tracking active I/O and waiting for it during removal.
This helped with the original test, but I found a problem with my accounting
for asynchronous transfer_one_message() controllers.
spi_finalize_current_message() signals cur_msg_completion before calling the
message's completion callback. In my experimental patch, the pump can
therefore drop the active I/O count before that callback returns.
I confirmed this with a fake controller and a non-sleeping callback using a
bounded busy-wait to expose the ordering. spi_unregister_controller() returned
while the callback had entered but not exited. The test produced no KASAN
report; it was intended to demonstrate the ordering, not a separate UAF. The
fake peripheral driver deliberately left an asynchronous request outstanding
during remove().
I also found that core-side accounting cannot protect private resources that
a peripheral driver frees while its own asynchronous callbacks can still
access them.
I've stopped work on the experimental patch for now. Before extending it, I'd
appreciate your guidance on two points:
1. Is it the peripheral driver's responsibility to stop new requests and
drain outstanding asynchronous callbacks before releasing private
resources in remove(), including requests submitted during removal?
2. If a controller cannot terminate an active transfer, should its driver
ensure that the transfer completes before unregister returns? Given that
spi_unregister_controller() returns void, would the core need a different
contract to handle an unabortable transfer safely?
I can provide the test module, logs and experimental diff if useful.
Thanks,
Yaohan