DMA Engine development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Rosen Penev" <rosenp@gmail.com>
Cc: vkoul@kernel.org, dmaengine@vger.kernel.org, Frank.Li@kernel.org
Subject: Re: [PATCHv3 01/15] dmaengine: fsldma: kill tasklet before removing channel
Date: Tue, 09 Jun 2026 22:31:31 +0000	[thread overview]
Message-ID: <20260609223132.060021F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260609221926.35538-2-rosenp@gmail.com>

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

Pre-existing issues:
- [High] Unhandled Error Return from dma_async_device_register() leads to silent probe failure and resource leaks.
- [High] Off-by-one error in the fsldma_request_irqs() error unwind path attempts to free the IRQ that just failed to be requested.
- [High] Double unlock in fsldma_suspend_late() error path causes unbalanced spinlocks.
- [High] Client callback is invoked with the channel descriptor spinlock held, which can lead to a self-deadlock.
--

commit 89849d3f67e5b5c4ccce67310ff8f24602b221dc
Author: Rosen Penev <rosenp@gmail.com>

dmaengine: fsldma: kill tasklet before removing channel
    
Add tasklet_kill() in fsl_dma_chan_remove() to prevent a race
where the tasklet, scheduled by the IRQ handler, runs after
the channel has been freed.

> diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
> index 22d62d958abd9..0e2f84862261c 100644
> --- a/drivers/dma/fsldma.c
> +++ b/drivers/dma/fsldma.c
> @@ -1205,6 +1205,7 @@ static int fsl_dma_chan_probe(struct fsldma_device *fdev,
>  
>  static void fsl_dma_chan_remove(struct fsldma_chan *chan)
>  {
> +	tasklet_kill(&chan->tasklet);
>  	irq_dispose_mapping(chan->irq);
>  	list_del(&chan->common.device_node);
>  	iounmap(chan->regs);

[Severity: High]
This is a pre-existing issue, but does fsldma_of_probe() ignore the return
value of dma_async_device_register()?

If registration fails due to an IDA allocation error, the probe function
unconditionally returns 0, falsely reporting success to the driver core.
Later, when the device is removed, fsldma_of_remove() will call
dma_async_device_unregister() on a device that was never fully registered.

Can this corrupt IDA states or trigger assertions and kernel panics?

Will allocated resources like memory, IRQs, and iomappings leak because the
error cleanup path is bypassed?

drivers/dma/fsldma.c:fsldma_of_probe() {
    ...
	dma_async_device_register(&fdev->common);
	return 0;
}

[Severity: High]
This is a pre-existing issue, but could the rollback loop in
fsldma_request_irqs() be missing a decrement of 'i' before the first
iteration?

If request_irq() fails for a channel at index 'i', the code jumps to
out_unwind and begins the cleanup loop starting at the exact same index 'i'.
It unconditionally calls free_irq() for this channel. Because request_irq()
just failed, the IRQ was never successfully allocated.

Will calling free_irq() on an unrequested IRQ trigger a kernel warning?

drivers/dma/fsldma.c:fsldma_request_irqs() {
    ...
out_unwind:
	for (/* none */; i >= 0; i--) {
		chan = fdev->chan[i];
		if (!chan)
			continue;

		if (!chan->irq)
			continue;

		free_irq(chan->irq, chan);
	}
}

[Severity: High]
This is a pre-existing issue, but are we double unlocking chan->desc_lock
in the error path of fsldma_suspend_late()?

In fsldma_suspend_late(), the forward loop acquires the lock, updates state,
and releases it. If a subsequent channel is not idle, it jumps to out: and
iterates backward, unlocking all previously processed channels:

drivers/dma/fsldma.c:fsldma_suspend_late() {
    ...
out:
	for (; i >= 0; i--) {
		chan = fdev->chan[i];
		if (!chan)
			continue;
		chan->pm_state = RUNNING;
		spin_unlock_bh(&chan->desc_lock);
	}
}

Since the locks for these earlier channels were already released during the
forward iteration, might this corrupt the lock state and local_bh preemption
count, leading to warnings and potential crashes?

[Severity: High]
This is a pre-existing issue, but is the client callback invoked with the
channel descriptor spinlock held?

In dma_do_tasklet(), chan->desc_lock is acquired before cleaning up completed
descriptors:

drivers/dma/fsldma.c:dma_do_tasklet() {
    ...
	spin_lock(&chan->desc_lock);

	/* the hardware is now idle and ready for more */
	chan->idle = true;

	/* Run all cleanup for descriptors which have been completed */
	fsldma_cleanup_descriptors(chan);
    ...
}

The cleanup chain eventually calls dmaengine_desc_get_callback_invoke()
without dropping the spinlock:

drivers/dma/fsldma.c:fsldma_run_tx_complete_actions() {
    ...
		/* Run the link descriptor callback function */
		dmaengine_desc_get_callback_invoke(txd, NULL);
    ...
}

If the client callback attempts to submit new transfers, it reaches
fsl_dma_tx_submit() which attempts to acquire the same non-recursive lock:

drivers/dma/fsldma.c:fsl_dma_tx_submit() {
    ...
	spin_lock_bh(&chan->desc_lock);
    ...
}

Could this lead to a self-deadlock?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260609221926.35538-2-rosenp@gmail.com?part=1

  reply	other threads:[~2026-06-09 22:31 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09 22:19 [PATCHv3 00/15] dmaengine: fsldma: devm conversion, fixups, and cleanups Rosen Penev
2026-06-09 22:19 ` [PATCHv3 01/15] dmaengine: fsldma: kill tasklet before removing channel Rosen Penev
2026-06-09 22:31   ` sashiko-bot [this message]
2026-06-10  1:35   ` Frank Li
2026-06-09 22:19 ` [PATCHv3 02/15] dmaengine: fsldma: drop desc_lock before invoking client callback Rosen Penev
2026-06-09 22:32   ` sashiko-bot
2026-06-09 22:19 ` [PATCHv3 03/15] dmaengine: fsldma: halt DMA engine before freeing resources Rosen Penev
2026-06-10  2:46   ` Frank Li
2026-06-09 22:19 ` [PATCHv3 04/15] dmaengine: fsldma: provide device_release callback Rosen Penev
2026-06-09 22:29   ` sashiko-bot
2026-06-09 22:19 ` [PATCHv3 05/15] dmaengine: fsldma: check dma_async_device_register() return value Rosen Penev
2026-06-09 22:29   ` sashiko-bot
2026-06-09 22:19 ` [PATCHv3 06/15] dmaengine: fsldma: fix probe error path not freeing IRQs Rosen Penev
2026-06-09 22:19 ` [PATCHv3 07/15] dmaengine: fsldma: fix request_irqs unwind freeing unregistered IRQ Rosen Penev
2026-06-09 22:28   ` sashiko-bot
2026-06-09 22:19 ` [PATCHv3 08/15] dmaengine: fsldma: convert to platform_get_irq_optional() Rosen Penev
2026-06-10  2:58   ` Frank Li
2026-06-09 22:19 ` [PATCHv3 09/15] dmaengine: fsldma: use devm for kzalloc() Rosen Penev
2026-06-10  1:57   ` Frank Li
2026-06-09 22:19 ` [PATCHv3 10/15] dmaengine: fsldma: use devm_platform_ioremap_resource() Rosen Penev
2026-06-09 22:19 ` [PATCHv3 11/15] dmaengine: fsldma: convert channel allocation to devm_kzalloc() Rosen Penev
2026-06-09 22:19 ` [PATCHv3 12/15] dmaengine: fsldma: use devm for of_iomap() Rosen Penev
2026-06-10  1:53   ` Frank Li
2026-06-09 22:19 ` [PATCHv3 13/15] dmaengine: fsldma: replace irq_of_parse_and_map with of_irq_get Rosen Penev
2026-06-09 22:36   ` sashiko-bot
2026-06-09 22:19 ` [PATCHv3 14/15] dmaengine: fsldma: replace ppc-specific accessors with portable generic ones Rosen Penev
2026-06-09 22:19 ` [PATCHv3 15/15] dmaengine: fsldma: fix kernel-doc param names to match function signatures Rosen Penev

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=20260609223132.060021F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=rosenp@gmail.com \
    --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