All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: Frank.Li@oss.nxp.com
Cc: dmaengine@vger.kernel.org, imx@lists.linux.dev, vkoul@kernel.org,
	Frank.Li@kernel.org, linux-pci@vger.kernel.org
Subject: Re: [PATCH v4 10/10] dmaengine: dw-edma: Remove struct dw_edma_chunk
Date: Wed, 08 Jul 2026 18:47:28 +0000	[thread overview]
Message-ID: <20260708184728.F182D1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260708-edma_ll-v4-10-cc128f0afb61@nxp.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [High] Replacing chunked allocations with a single, unbounded array allocation causes a severe risk of `GFP_NOWAIT` failures for large transfers.
- [High] The device TX status calculation incorrectly subtracts the size of the uncompleted burst instead of the last completed burst, resulting in an under-reported residue.
- [High] Double subtraction of the link descriptor limit in `dw_edma_core_start()` incorrectly limits chunk sizes and causes a hardware hang for small link regions.

Pre-existing issues:
- [High] The functions `dw_edma_device_resume`, `dw_edma_device_pause`, and `dw_edma_device_terminate_all` modify channel states and access descriptor lists without holding `chan->vc.lock`.
--

--- Patch [10]: [PATCH v4 10/10] dmaengine: dw-edma: Remove struct dw_edma_chunk ---
commit 4d352ddf553a3f2f63c8953fcbcf205cb6c98a87
Author: Frank Li <Frank.Li@nxp.com>

dmaengine: dw-edma: Remove struct dw_edma_chunk

This commit removes the dw_edma_chunk layer to simplify the descriptor
layout, embedding the burst array directly into dw_edma_desc. It aims
to reduce the number of kzalloc calls when creating a DMA descriptor.

> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index 01bee22fe3b3e..474debb53c470 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
[ ... ]
> @@ -40,82 +40,54 @@ u64 dw_edma_get_pci_address(struct dw_edma_chan *chan, phys_addr_t cpu_addr)
[ ... ]
> -static struct dw_edma_desc *dw_edma_alloc_desc(struct dw_edma_chan *chan)
> +static struct dw_edma_desc *
> +dw_edma_alloc_desc(struct dw_edma_chan *chan, u32 nburst)
>  {
>  	struct dw_edma_desc *desc;
>  
> -	desc = kzalloc_obj(*desc, GFP_NOWAIT);
> +	desc = kzalloc_flex(*desc, burst, nburst, GFP_NOWAIT);

[Severity: High]
Does this unbounded allocation risk failing under memory fragmentation?

The previous logic used bounded chunk sizes, but nburst is now passed directly
from the scatter-gather list length or interleaved frames in
dw_edma_device_transfer(), which could be thousands of entries. Allocating a
large contiguous array in an atomic context with GFP_NOWAIT seems highly prone
to failure for large transfers.

>  	if (unlikely(!desc))
>  		return NULL;
[ ... ]
> -static void dw_edma_core_start(struct dw_edma_chunk *chunk, bool first)
> +static void dw_edma_core_start(struct dw_edma_desc *desc, bool first)
>  {
[ ... ]
> +	for (i = 0; i + desc->start_burst < desc->nburst; i++) {
> +		u32 idx = i + desc->start_burst;
>  
> -	dw_edma_core_ll_link(chan, i, chunk->cb, chan->ll_region.paddr);
> +		if (i == chan->ll_max - 1)
> +			break;

[Severity: High]
Does this double-subtract the link descriptor limit?

chan->ll_max is initialized elsewhere as (sz / EDMA_LL_SZ) - 1 to account for
the link descriptor. If chan->ll_max is 1, breaking at i == 0 submits a batch
with 0 data elements. Could this immediately complete and fire an interrupt,
potentially triggering an infinite loop of 0-length transfers?

> +
> +		dw_edma_core_ll_data(chan, &desc->burst[idx],
> +				     i, desc->cb,
> +				     idx == desc->nburst - 1 || i == chan->ll_max - 2);
> +	}
[ ... ]
> @@ -337,8 +301,10 @@ dw_edma_device_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
>  	vd = vchan_find_desc(&chan->vc, cookie);
>  	if (vd) {
>  		desc = vd2dw_edma_desc(vd);
> -		if (desc)
> -			residue = desc->alloc_sz - desc->xfer_sz;
> +
> +		residue = desc->alloc_sz;
> +		if (desc && desc->done_burst)
> +			residue -= desc->burst[desc->done_burst].xfer_sz;

[Severity: High]
Should this calculation use desc->done_burst - 1 instead of desc->done_burst?

desc->done_burst holds the index of the first burst currently executing in
hardware. Subtracting desc->burst[desc->done_burst].xfer_sz includes the size
of an unfinished burst, which under-reports the residue. This differs from
dw_hdma_set_callback_result() which uses desc->done_burst - 1.

>  	}
>  	spin_unlock_irqrestore(&chan->vc.lock, flags);
[ ... ]

[Severity: High]
This isn't a bug introduced by this patch, but looking at
dw_edma_device_resume() and dw_edma_device_pause() in
drivers/dma/dw-edma/dw-edma-core.c:

dw_edma_device_resume()
    chan->status = EDMA_ST_BUSY;
    dw_edma_start_transfer(chan);

dw_edma_device_pause()
    chan->request = EDMA_REQ_PAUSE;

Can modifying the channel state and calling dw_edma_start_transfer() (which
accesses vc->desc_issued) locklessly cause data races?

Other functions like dw_edma_device_issue_pending() and
dw_edma_done_interrupt() protect these structures with
spin_lock_irqsave(&chan->vc.lock, flags).

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260708-edma_ll-v4-0-cc128f0afb61@nxp.com?part=10

  reply	other threads:[~2026-07-08 18:47 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08 18:35 [PATCH v4 00/10] dmaengine: dw-edma: flatten desc structions and simple code Frank.Li
2026-07-08 18:35 ` [PATCH v4 01/10] dmaengine: dw-edma: Move control field update of DMA link to the last step Frank.Li
2026-07-08 18:47   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 02/10] dmaengine: dw-edma: Add xfer_sz field to struct dw_edma_chunk Frank.Li
2026-07-08 18:49   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 03/10] dmaengine: dw-edma: Move ll_region from struct dw_edma_chunk to struct dw_edma_chan Frank.Li
2026-07-08 18:46   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 04/10] dmaengine: dw-edma: Pass down dw_edma_chan to reduce one level of indirection Frank.Li
2026-07-08 18:44   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 05/10] dmaengine: dw-edma: Add helper dw_(edma|hdma)_v0_core_ch_enable() Frank.Li
2026-07-08 18:40   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 06/10] dmaengine: dw-edma: Add callbacks to fill link list entries Frank.Li
2026-07-08 18:51   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 07/10] dmaengine: dw-edma: Add non_ll_start() callback Frank.Li
2026-07-08 18:49   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 08/10] dmaengine: dw-edma: Use common dw_edma_core_start() for both eDMA and HDMA Frank.Li
2026-07-08 18:56   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 09/10] dmaengine: dw-edma: Use burst array instead of linked list Frank.Li
2026-07-08 18:49   ` sashiko-bot
2026-07-08 18:35 ` [PATCH v4 10/10] dmaengine: dw-edma: Remove struct dw_edma_chunk Frank.Li
2026-07-08 18:47   ` sashiko-bot [this message]
2026-07-09 11:33 ` [PATCH v4 00/10] dmaengine: dw-edma: flatten desc structions and simple code Markus Elfring

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=20260708184728.F182D1F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=Frank.Li@oss.nxp.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=imx@lists.linux.dev \
    --cc=linux-pci@vger.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 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.