All of lore.kernel.org
 help / color / mirror / Atom feed
From: Niklas Cassel <cassel@kernel.org>
To: Damien Le Moal <dlemoal@kernel.org>
Cc: linux-ide@vger.kernel.org, Niklas Cassel <cassel@kernel.org>,
	stable@vger.kernel.org
Subject: [PATCH] ata: libahci: Stop the SW activity blink timers on port suspend
Date: Tue, 10 Nov 2026 14:56:16 +0100	[thread overview]
Message-ID: <20261110135615.291884-2-cassel@kernel.org> (raw)

The SW activity blink timers are not stopped when a port is suspended.
Every command goes through ahci_qc_issue() -> ahci_sw_activity(), so
with SW activity enabled, a blink timer can still be pending when
ahci_port_suspend() runs, e.g. armed by the commands issued just before
it, and ahci_sw_activity_blink() re-arms it as long as there was
activity.

If the timer fires while the port is suspended, ahci_sw_activity_blink()
-> ahci_transmit_led_message() -> ahci_rpm_get_port() calls
pm_runtime_get_sync() from timer softirq context, and the EM registers
of a suspended controller get written. If the port is resumed while the
timer is still pending, ahci_port_resume() -> ahci_start_port() ->
ahci_init_sw_activity() calls timer_setup() on a timer that is still
queued in the timer wheel, corrupting it.

Stop the timers in ahci_port_suspend(). Use timer_delete_sync() rather
than timer_shutdown_sync(): the timers are only stopped until the port
is resumed, while timer_shutdown_sync() is meant for timers that are
torn down for good.

Fixes: 18f7ba4c2f4b ("libata/ahci: enclosure management support")
Cc: stable@vger.kernel.org
Signed-off-by: Niklas Cassel <cassel@kernel.org>
---
Developed with the assistance of an LLM.

Tested in QEMU (q35, KVM) with KASAN, UBSAN, DEBUG_OBJECTS_TIMERS and
lockdep, using TEST-ONLY hooks: one fakes enclosure management (QEMU's
AHCI has none), the other arms the blink timer as ahci_qc_issue() does
and then calls ->port_suspend() and ->port_resume() back to back, while
the timer is still pending.

  unpatched                              patched
  ODEBUG: init active ... timer_list     no warnings,
  hint: ahci_sw_activity_blink,          I/O after resume works
  from ahci_port_resume()

The timer firing while the port is suspended is not covered, as the
fake EM support never reaches ahci_rpm_get_port().

 drivers/ata/libahci.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index ef760d81d1d1..2e71ba7ea374 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -2491,8 +2491,21 @@ static void ahci_handle_s2idle(struct ata_port *ap)
 
 static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
 {
+	struct ahci_port_priv *pp = ap->private_data;
 	const char *emsg = NULL;
-	int rc;
+	int rc, i;
+
+	/*
+	 * Stop the SW activity blink timers, so that they cannot fire while
+	 * the port is suspended. ahci_init_sw_activity() sets them up again
+	 * on resume.
+	 */
+	for (i = 0; i < EM_MAX_SLOTS; i++) {
+		struct ahci_em_priv *emp = &pp->em_priv[i];
+
+		if (emp->timer.function)
+			timer_delete_sync(&emp->timer);
+	}
 
 	rc = ahci_deinit_port(ap, &emsg);
 	if (rc == 0)
-- 
2.56.0


             reply	other threads:[~2026-11-10 13:56 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 13:56 Niklas Cassel [this message]
2026-11-11 23:35 ` [PATCH] ata: libahci: Stop the SW activity blink timers on port suspend Damien Le Moal

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=20261110135615.291884-2-cassel@kernel.org \
    --to=cassel@kernel.org \
    --cc=dlemoal@kernel.org \
    --cc=linux-ide@vger.kernel.org \
    --cc=stable@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 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.