From: sashiko-bot@kernel.org
To: "Linus Walleij" <linusw@kernel.org>
Cc: vkoul@kernel.org, Frank.Li@kernel.org, dmaengine@vger.kernel.org
Subject: Re: [PATCH v3 02/22] dmaengine: ste_dma40: Fix cyclic transfer residue
Date: Fri, 18 Sep 2026 16:44:51 +0000 [thread overview]
Message-ID: <20260918164451.EF67E1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260918-dma40-fixes-v3-2-8dd8450669e8@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] dmaengine: ste_dma40: unvalidated cyclic period length causes state corruption
- [Medium] dmaengine: ste_dma40: race condition in cyclic residue calculation
--
commit 80bd7a5b773ac08dae8cfb0539ed88005fe2df44
Author: Linus Walleij <linusw@kernel.org>
dmaengine: ste_dma40: Fix cyclic transfer residue
DMA40 reads residue from the element count of the currently active LLI.
For a cyclic transfer this reports at most one period, not the bytes
remaining until the cyclic buffer wraps. This patch tracks the active
period of cyclic descriptors and adds all later periods in the buffer to
the current LLI residue.
> diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
> --- a/drivers/dma/ste_dma40.c
> +++ b/drivers/dma/ste_dma40.c
[ ... ]
> @@ -2108,15 +2120,27 @@ static bool d40_is_paused(struct d40_chan *d40c)
>
> }
>
> -static u32 stedma40_residue(struct dma_chan *chan)
> +static u32 stedma40_residue(struct dma_chan *chan, dma_cookie_t cookie)
> {
> struct d40_chan *d40c =
> container_of(chan, struct d40_chan, chan);
> + struct d40_desc *d40d;
> u32 bytes_left;
> unsigned long flags;
>
> spin_lock_irqsave(&d40c->lock, flags);
> bytes_left = d40_residue(d40c);
> +
> + d40d = d40_first_active_get(d40c);
> + /*
> + * The hardware residue is for the current LLI. Cyclic transfers use
> + * one LLI for each period, so include the later periods in the buffer.
> + */
> + if (d40d && d40d->txd.cookie == cookie && d40d->cyclic &&
> + d40d->cyclic_period_len)
> + bytes_left += d40d->cyclic_buf_len - d40d->cyclic_pos -
> + d40d->cyclic_period_len;
[Severity: Medium]
Can this create a race condition when a client asynchronously polls the DMA
residue?
If the hardware has just completed a period and advanced its internal LLI,
but the terminal-count interrupt hasn't updated the software cyclic_pos yet:
dma_tc_handle() {
...
if (d40d->cyclic_period_len) {
d40d->cyclic_pos += d40d->cyclic_period_len;
...
}
Could stedma40_residue() read the current hardware residue without
synchronizing with the interrupt handler's update, causing the residue (and
pointers for clients like ALSA) to occasionally jump backward and cause audio
glitches?
[ ... ]
> @@ -2524,11 +2548,17 @@ dma40_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr,
> size_t buf_len, size_t period_len,
> enum dma_transfer_direction direction, unsigned long flags)
> {
> - unsigned int periods = buf_len / period_len;
> struct dma_async_tx_descriptor *txd;
> + struct d40_desc *desc;
> struct scatterlist *sg;
> int i;
>
> + if (!buf_len || !period_len || buf_len % period_len)
> + return NULL;
> +
> + periods = buf_len / period_len;
[Severity: High]
Does this also need to validate that period_len is within the hardware's
maximum segment size?
If a cyclic period_len exceeds the maximum segment size (for example,
STEDMA40_MAX_SEG_SIZE * data_width), it seems it would be silently split
into multiple LLIs. For logical channels, every LLI unconditionally
triggers a terminal-count interrupt.
If that happens, wouldn't dma_tc_handle() erroneously advance cyclic_pos
by the full period_len on every LLI interrupt?
dma_tc_handle() {
...
if (d40d->cyclic_period_len) {
d40d->cyclic_pos += d40d->cyclic_period_len;
...
}
This seems like it would permanently drift the residue tracking in
stedma40_residue() and trigger excessive callbacks if a client requests a
large cyclic buffer.
>
> sg = kzalloc_objs(struct scatterlist, periods + 1, GFP_NOWAIT);
> if (!sg)
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260918-dma40-fixes-v3-0-8dd8450669e8@kernel.org?part=2
next prev parent reply other threads:[~2026-09-18 16:44 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 16:24 [PATCH v3 00/22] dmaengine: ste_dma40: Fix numerous accumulated bugs Linus Walleij
2026-09-18 16:24 ` [PATCH v3 01/22] dmaengine: ste_dma40: Fix physical cyclic capability Linus Walleij
2026-09-18 19:57 ` Frank Li
2026-09-18 16:24 ` [PATCH v3 02/22] dmaengine: ste_dma40: Fix cyclic transfer residue Linus Walleij
2026-09-18 16:44 ` sashiko-bot [this message]
2026-09-18 21:41 ` Frank Li
2026-09-18 16:24 ` [PATCH v3 03/22] dmaengine: ste_dma40: Fix failed start cleanup Linus Walleij
2026-09-18 16:24 ` [PATCH v3 04/22] dmaengine: ste_dma40: Fix probe runtime PM disable Linus Walleij
2026-09-18 16:24 ` [PATCH v3 05/22] dmaengine: ste_dma40: Check runtime PM in IRQ Linus Walleij
2026-09-18 16:24 ` [PATCH v3 06/22] dmaengine: ste_dma40: Handle runtime PM resume errors Linus Walleij
2026-09-18 16:37 ` sashiko-bot
2026-09-18 16:24 ` [PATCH v3 07/22] dmaengine: ste_dma40: Return IRQ_NONE without interrupt status Linus Walleij
2026-09-18 16:24 ` [PATCH v3 08/22] dmaengine: ste_dma40: Init hardware before registration Linus Walleij
2026-09-18 16:24 ` [PATCH v3 09/22] dmaengine: ste_dma40: Fix probe IRQ leak Linus Walleij
2026-09-18 16:24 ` [PATCH v3 10/22] dmaengine: ste_dma40: Fix DMA registration unwind Linus Walleij
2026-09-18 16:24 ` [PATCH v3 11/22] dmaengine: ste_dma40: Fix LCLA allocation order Linus Walleij
2026-09-18 16:24 ` [PATCH v3 12/22] dmaengine: ste_dma40: Fix probe LCLA free Linus Walleij
2026-09-18 16:24 ` [PATCH v3 13/22] dmaengine: ste_dma40: Put the LCPA SRAM node Linus Walleij
2026-09-18 16:24 ` [PATCH v3 14/22] dmaengine: ste_dma40: Fix memcpy channel parsing Linus Walleij
2026-09-18 16:24 ` [PATCH v3 15/22] dmaengine: ste_dma40: Validate disabled channel indexes Linus Walleij
2026-09-18 16:24 ` [PATCH v3 16/22] dmaengine: ste_dma40: Validate DMA specifier length Linus Walleij
2026-09-18 16:24 ` [PATCH v3 17/22] dmaengine: ste_dma40: Reject direction changes after allocation Linus Walleij
2026-09-18 16:24 ` [PATCH v3 18/22] dmaengine: ste_dma40: Fix logical channel bounds check Linus Walleij
2026-09-18 16:24 ` [PATCH v3 19/22] dmaengine: ste_dma40: Fix event group bounds Linus Walleij
2026-09-18 16:24 ` [PATCH v3 20/22] dmaengine: ste_dma40: Search all blocks for fixed logical channels Linus Walleij
2026-09-18 16:24 ` [PATCH v3 21/22] dmaengine: ste_dma40: Validate fixed physical channel indexes Linus Walleij
2026-09-18 16:24 ` [PATCH v3 22/22] dmaengine: ste_dma40: Validate memcpy configuration Linus Walleij
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=20260918164451.EF67E1F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=linusw@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@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