From: sashiko-bot@kernel.org
To: "Shih-Yuan Lee" <fourdollars@debian.org>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [PATCH v3 1/5] Input: applespi - use unified wait queue with timeouts for drain
Date: Mon, 20 Jul 2026 16:46:52 +0000 [thread overview]
Message-ID: <20260720164652.8842E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260720162219.32324-2-fourdollars@debian.org>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Medium] The patch attempts to prevent indefinite lockups during driver unbind or PM transitions by adding a timeout to the drain waits. However, upon timeout, it explicitly falls back to waiting unconditionally on the exact same condition, neutralizing the protection and still causing an indefinite lockup.
- [Low] Unnecessary removal of scope-based cleanup `guard()`, reverting to manual spinlock management.
Pre-existing issues:
- [Critical] Missing cancel_work_sync() in applespi_remove() causes Use-After-Free of applespi_data when the workqueue executes.
--
--- Patch [1]: [PATCH v3 1/5] Input: applespi - use unified wait queue with timeouts for drain ---
commit 08fd2aeb0171b9531113cd115a28c72f63462dc0
Author: Shih-Yuan Lee <fourdollars@debian.org>
Input: applespi - use unified wait queue with timeouts for drain
Consolidate wait queues by renaming drain_complete to wait_queue and use
wait_event_lock_irq_timeout() with a 3-second timeout during read and write
drains to prevent indefinite lockups during driver unbind or PM transitions
if the hardware becomes unresponsive.
> diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c
> index b5ff71cd5a701..c501bf7e517e4 100644
> --- a/drivers/input/keyboard/applespi.c
> +++ b/drivers/input/keyboard/applespi.c
[ ... ]
> @@ -1793,21 +1793,49 @@ static int applespi_probe(struct spi_device *spi)
>
> static void applespi_drain_writes(struct applespi_data *applespi)
> {
> - guard(spinlock_irqsave)(&applespi->cmd_msg_lock);
> + unsigned long flags;
> + long ret;
> +
> + spin_lock_irqsave(&applespi->cmd_msg_lock, flags);
[Severity: Low]
This isn't a bug, but is it necessary to revert from guard() to manual
spin_lock_irqsave() here?
The input subsystem guidelines prefer using modern cleanup primitives like
guard() in new or refactored code. wait_event_lock_irq_timeout() should
work correctly with the hidden flags variable established by guard().
>
> applespi->drain = true;
> - wait_event_lock_irq(applespi->drain_complete, !applespi->write_active,
> - applespi->cmd_msg_lock);
> + ret = wait_event_lock_irq_timeout(applespi->wait_queue,
> + !applespi->write_active,
> + applespi->cmd_msg_lock,
> + msecs_to_jiffies(3000));
> + if (!ret && applespi->write_active) {
> + dev_warn(&applespi->spi->dev,
> + "Timed out waiting for write drain, waiting unconditionally\n");
> + wait_event_lock_irq(applespi->wait_queue,
> + !applespi->write_active,
> + applespi->cmd_msg_lock);
[Severity: Medium]
Does this fallback logic defeat the purpose of the timeout?
The commit message states the timeout is meant to prevent indefinite lockups,
but if a timeout occurs here, wait_event_lock_irq() waits unconditionally
on the exact same condition.
If the hardware is genuinely unresponsive, won't this just delay the indefinite
lockup by 3 seconds rather than preventing it?
> + }
> +
> + spin_unlock_irqrestore(&applespi->cmd_msg_lock, flags);
> }
>
> static void applespi_drain_reads(struct applespi_data *applespi)
> {
> - guard(spinlock_irqsave)(&applespi->cmd_msg_lock);
> + unsigned long flags;
> + long ret;
>
> - wait_event_lock_irq(applespi->drain_complete, !applespi->read_active,
> - applespi->cmd_msg_lock);
> + spin_lock_irqsave(&applespi->cmd_msg_lock, flags);
> +
> + ret = wait_event_lock_irq_timeout(applespi->wait_queue,
> + !applespi->read_active,
> + applespi->cmd_msg_lock,
> + msecs_to_jiffies(3000));
> + if (!ret && applespi->read_active) {
> + dev_warn(&applespi->spi->dev,
> + "Timed out waiting for read drain, waiting unconditionally\n");
> + wait_event_lock_irq(applespi->wait_queue,
> + !applespi->read_active,
> + applespi->cmd_msg_lock);
[Severity: Medium]
Does this read drain fallback have the same indefinite lockup issue as the
write drain when the hardware fails?
> + }
>
> applespi->suspended = true;
> +
> + spin_unlock_irqrestore(&applespi->cmd_msg_lock, flags);
> }
>
> static void applespi_remove(struct spi_device *spi)
[Severity: Critical]
This is a pre-existing issue, but does applespi_remove() miss a call to
cancel_work_sync(&applespi->work) before returning?
If the driver unbinds while a touchpad info SPI transaction is in flight,
applespi_drain_reads() will block until the read finishes.
When the SPI read completes, its handler schedules applespi->work, clears
read_active, and wakes up the drain.
If applespi_remove() finishes without cancelling the work, devres will
free applespi_data, which could lead to a use-after-free when the scheduled
applespi_worker() executes.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720162219.32324-1-fourdollars@debian.org?part=1
next prev parent reply other threads:[~2026-07-20 16:46 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 16:22 [PATCH v3 0/5] Input: applespi - Fix probe timeout and use-after-free bugs Shih-Yuan Lee
2026-07-20 16:22 ` [PATCH v3 1/5] Input: applespi - use unified wait queue with timeouts for drain Shih-Yuan Lee
2026-07-20 16:46 ` sashiko-bot [this message]
2026-07-20 16:22 ` [PATCH v3 2/5] Input: applespi - track asynchronous SPI transfers in flight Shih-Yuan Lee
2026-07-20 16:36 ` sashiko-bot
2026-07-20 16:22 ` [PATCH v3 3/5] Input: applespi - register touchpad synchronously in probe Shih-Yuan Lee
2026-07-20 16:22 ` [PATCH v3 4/5] Input: applespi - prefer asynchronous driver probing Shih-Yuan Lee
2026-07-20 16:38 ` sashiko-bot
2026-07-20 16:22 ` [PATCH v3 5/5] Input: applespi - fix use-after-free in applespi_remove() Shih-Yuan Lee
2026-07-20 16:37 ` sashiko-bot
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=20260720164652.8842E1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=fourdollars@debian.org \
--cc=linux-input@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.