Re: [PATCH v4 22/24] dmaengine: dw-edma: Add engine recovery infrastructure

[email protected] Wed, 29 Jul 2026 15:02:22 +0000
Newsgroups org.kernel.vger.dmaengine
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(=
s) to consider:
- [High] Hardware engine is left permanently disabled if a stalled transfer=
 completes spontaneously during the engine_reset retry loop.
--

--- Patch [22]: [PATCH v4 22/24] dmaengine: dw-edma: Add engine recovery in=
frastructure ---
commit d5fd1986862b1ea5049e2ba48c784328b9d2d605
Author: Koichiro Den <[email protected]>

dmaengine: dw-edma: Add engine recovery infrastructure

This commit introduces an engine recovery worker for eDMA to coordinate
resets across all channels in a given direction when a transfer stalls.
It gates channels, attempts to quiesce active LL channels, resets the
engine, and rebuilds LL contexts before re-enabling the direction.

> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-=
edma-core.c
> index cbe60bcd4c9a0..616b0658b1ef3 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
[ ... ]
> @@ -785,6 +809,283 @@ static void dw_edma_ll_recheck_work(struct work_str=
uct *work)
[ ... ]
> +static void dw_edma_engine_recovery_work(struct work_struct *work)
> +{
> +	struct dw_edma_engine_recovery *rec =3D
> +		container_of(to_delayed_work(work),
> +			     struct dw_edma_engine_recovery, work);
> +	struct dw_edma *dw =3D rec->dw;
[ ... ]
> +	if (unlikely(READ_ONCE(dw->teardown)))
> +		return;
> +
> +	if (!dw_edma_engine_recovery_needed(rec)) {
> +		if (READ_ONCE(rec->active))
> +			dw_edma_engine_recovery_release(rec);
> +		return;
> +	}

[Severity: High]
Could the hardware engine be left permanently disabled if a stalled transfer
completes spontaneously during the engine_reset retry loop?

If dw->core->engine_reset() fails later in this worker, it disables the
engine by writing 0 to ENGINE_EN but may time out waiting for it to read
back as 0. This returns false and queues a retry.

If the hardware unsticks before that retry executes, the next call to
dw_edma_engine_recovery_needed(rec) will evaluate to false. This triggers
the early exit path above, calling dw_edma_engine_recovery_release().

While dw_edma_engine_recovery_release() ungates the channels, it never
calls dw->core->engine_enable(). Because ENGINE_EN was previously written
to 0 during the failed reset attempt, does this mean the engine remains
stopped and will drop all future transfers?

--=20
Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260729143036.3087=
[email protected]?part=3D22