mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Yaohan Li <shunsheng1218@gmail.com>
To: Mark Brown <broonie@kernel.org>
Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC] spi: handling a stuck queue worker during controller unregister
Date: Sat, 14 Nov 2026 10:17:37 +0800	[thread overview]
Message-ID: <179462265760.266954.15125504985835019625@gmail.com> (raw)
In-Reply-To: <03d73980-f558-4dd4-8ec1-a8d40bd2474d@sirena.org.uk>

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

      reply	other threads:[~2026-11-14  2:17 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04  4:57 zhang san
2026-11-08 13:59 ` Mark Brown
2026-11-14  2:17   ` Yaohan Li [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=179462265760.266954.15125504985835019625@gmail.com \
    --to=shunsheng1218@gmail.com \
    --cc=broonie@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®