From: sashiko-bot@kernel.org
To: "Rosen Penev" <rosenp@gmail.com>
Cc: cassel@kernel.org, dlemoal@kernel.org, linux-ide@vger.kernel.org
Subject: Re: [PATCHv2] ata: sata_dwc_460ex: preserve sactive_issued state across ISR invocations
Date: Tue, 08 Sep 2026 22:02:28 +0000 [thread overview]
Message-ID: <20260908220228.B0DE11F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260908214536.598823-1-rosenp@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [Critical] Preserving `sactive_issued` across ISR invocations causes repeated re-processing of completed DEV phases, prematurely completing NCQ commands.
- [High] NCQ DMAC interrupts are dropped when arriving before DEV interrupts, causing hangs.
- [High] Missing cleanup of `sactive_issued` for stale tags leads to infinite log spam and permanently breaks subsequent non-NCQ commands.
Pre-existing issues:
- [High] Out-of-bounds heap read when `ap->link.active_tag` is `ATA_TAG_POISON`.
--
commit 7a3914f790a5ca1a682aa2a68e7936ab121bdb65
Author: Rosen Penev <rosenp@gmail.com>
ata: sata_dwc_460ex: preserve sactive_issued state across ISR invocations
This patch stops zeroing hsdev->sactive_issued on every ISR entry to
preserve NCQ tag tracking across interrupts. It also updates the NCQ/non-NCQ
discrimination logic to prevent completion processing when tag_mask is zero
but the active command is NCQ.
> diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
> index 8e3fc713891af..a8eec3dc7eb17 100644
> --- a/drivers/ata/sata_dwc_460ex.c
> +++ b/drivers/ata/sata_dwc_460ex.c
[ ... ]
> @@ -517,8 +516,11 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
> sata_dwc_scr_read(&ap->link, SCR_ACTIVE, &sactive);
> tag_mask = (hsdev->sactive_issued | sactive) ^ sactive;
>
> - /* If no sactive issued and tag_mask is zero then this is not NCQ */
> - if (hsdev->sactive_issued == 0 && tag_mask == 0) {
> + /*
> + * If tag_mask is zero and the active command is not NCQ this is a
> + * non-NCQ completion.
> + */
> + if (tag_mask == 0) {
> if (ap->link.active_tag == ATA_TAG_POISON)
> tag = 0;
> else
[Severity: High]
This is a pre-existing issue, but since you are checking for ATA_TAG_POISON
here, I noticed that sata_dwc_error_intr() doesn't seem to do this.
When an error interrupt fires while no command is active, active_tag is
ATA_TAG_POISON (253). Does this out-of-bounds heap read leak memory into the
kernel log?
drivers/ata/sata_dwc_460ex.c:sata_dwc_error_intr() {
...
tag = ap->link.active_tag;
dev_err(ap->dev,
"... pending=%d issued=%d",
..., hsdevp->dma_pending[tag], hsdevp->cmd_issued[tag]);
...
}
> @@ -534,6 +536,12 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
> handled = 1;
> goto DONE;
> }
> + if (ata_is_ncq(qc->tf.protocol)) {
> + /* NCQ commands still in flight; no tag completed. */
> + ap->ops->sff_check_status(ap);
> + handled = 1;
> + goto DONE;
> + }
[Severity: High]
Does this early exit path drop NCQ DMAC interrupts when they arrive before DEV
interrupts?
In SATA DMA transactions, the DMAC (transfer complete) interrupt can arrive
before the device sends the SDB FIS (DEV interrupt). When this happens,
sactive still matches sactive_issued, so tag_mask is 0.
By exiting early here, it appears dma_interrupt_count will not be incremented
for the DMAC interrupt. When the DEV interrupt later arrives, the count will
only reach 1, potentially causing the NCQ command to permanently hang.
[ ... ]
> @@ -612,9 +620,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance)
> tag_mask &= ~(1U << tag);
> qc = ata_qc_from_tag(ap, tag);
> if (unlikely(!qc)) {
> - dev_err(ap->dev, "failed to get qc");
> - handled = 1;
> - goto DONE;
> + dev_err(ap->dev, "stale tag %d in NCQ completion",
> + tag);
> + continue;
> }
[Severity: High]
Because sactive_issued is persistent across ISR invocations now, does skipping
cleanup here permanently break the port?
If continue is taken (e.g., from a spurious hardware interrupt with an invalid
tag), the stale tag is never cleared from hsdev->sactive_issued. This seems
to cause tag_mask to evaluate to non-zero on all subsequent interrupts,
permanently breaking the non-NCQ early fallback path (which expects tag_mask
== 0) and potentially causing endless log spam.
[Severity: Critical]
Since sactive_issued is no longer cleared on ISR entry, does this loop need
to clear the completed tags from hsdev->sactive_issued?
Because pending tags are not cleared from sactive_issued until they fully
complete, they appear to be repeatedly processed on subsequent interrupts. If
multiple NCQ tags are active, a DEV interrupt for Tag A increments the global
dma_interrupt_count to 1 but does not clear sactive_issued.
If a DEV interrupt for Tag B arrives next, tag_mask still contains Tag A. The
loop processes Tag A again, increments the count to 2, and erroneously
completes Tag A before its DMAC interrupt arrives:
drivers/ata/sata_dwc_460ex.c:sata_dwc_isr() {
...
if (ata_is_dma(qc->tf.protocol)) {
hsdevp->dma_interrupt_count++;
...
if ((hsdevp->dma_interrupt_count % 2) == 0)
sata_dwc_dma_xfer_complete(ap);
...
}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260908214536.598823-1-rosenp@gmail.com?part=1
next prev parent reply other threads:[~2026-09-08 22:02 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 21:45 [PATCHv2] ata: sata_dwc_460ex: preserve sactive_issued state across ISR invocations Rosen Penev
2026-09-08 22:02 ` sashiko-bot [this message]
2026-09-09 10:08 ` Niklas Cassel
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=20260908220228.B0DE11F00A3D@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=cassel@kernel.org \
--cc=dlemoal@kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=rosenp@gmail.com \
--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.