From: sashiko-bot@kernel.org
To: "Claudiu Beznea" <claudiu.beznea@kernel.org>
Cc: vkoul@kernel.org, wsa+renesas@sang-engineering.com,
Frank.Li@kernel.org, dmaengine@vger.kernel.org
Subject: Re: [PATCH v6 15/18] dmaengine: sh: rz-dmac: Add suspend to RAM support
Date: Tue, 26 May 2026 09:43:10 +0000 [thread overview]
Message-ID: <20260526094311.123341F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260526084710.3491480-16-claudiu.beznea@kernel.org>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] The error recovery path in `rz_dmac_suspend()` fails to restore essential hardware registers before re-enabling cyclic channels.
- [High] Error paths in system suspend and resume callbacks fail to properly manage the runtime PM usage counter, causing an imbalance that leads to underflows.
- [High] The IRQ handler accesses hardware registers without verifying the device power state, risking a crash if an interrupt fires during or after system suspend.
- [Medium] The `rz_dmac_suspend()` function incorrectly mixes scope-based `guard()` locking with `goto`-based error handling.
--
commit 2944b998cf54bad86273dc3ee963623d49e8fffa
Author: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
dmaengine: sh: rz-dmac: Add suspend to RAM support
This patch adds suspend to RAM support for the Renesas RZ/G3S SoC DMA IP to
save and restore DMA IP registers. It adds specific handling for cyclic
channels by pausing and resuming them during system suspend/resume.
> diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
> index bd4ca8e939f17..2a7124e4aea3a 100644
> --- a/drivers/dma/sh/rz-dmac.c
> +++ b/drivers/dma/sh/rz-dmac.c
[ ... ]
> @@ -1421,6 +1474,122 @@ static void rz_dmac_remove(struct platform_device *pdev)
[ ... ]
> +static void rz_dmac_suspend_recover(struct rz_dmac *dmac)
> +{
> + int ret;
> +
> + PM_RUNTIME_ACQUIRE_IF_ENABLED(dmac->dev, pm);
> + ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> + if (ret)
> + return;
> +
> + for (unsigned int i = 0; i < dmac->n_channels; i++) {
> + struct rz_dmac_chan *channel = &dmac->channels[i];
> +
> + guard(spinlock_irqsave)(&channel->vc.lock);
> +
> + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC)))
> + continue;
> +
> + rz_dmac_device_resume_internal(channel);
[Severity: Critical]
Does this error recovery path fail to restore essential hardware registers
before re-enabling cyclic channels?
If pm_runtime_put_sync() fails in rz_dmac_suspend(), the driver jumps to
reset_deassert, calls reset_control_deassert(), and then executes this
function. However, the prior reset_control_assert() wiped the hardware state.
This function simply calls rz_dmac_device_resume_internal(), which writes
CHCTRL_SETEN to start the channel. Since essential configuration registers
like NXLA, CHCFG, and DCTRL are never restored, the hardware could attempt to
execute DMA transfers with zeroed configurations, potentially causing wild
memory accesses or silent data corruption.
> + }
> +}
> +
> +static int rz_dmac_suspend(struct device *dev)
> +{
> + struct rz_dmac *dmac = dev_get_drvdata(dev);
> + int ret = 0;
> +
> + for (unsigned int i = 0; i < dmac->n_channels; i++) {
> + struct rz_dmac_chan *channel = &dmac->channels[i];
> +
> + guard(spinlock_irqsave)(&channel->vc.lock);
[Severity: Medium]
Does this function mix guard() based locking with goto based error handling?
According to the subsystem cleanup guidelines, a single function must never
mix goto statements with __free() or guard() declarations. This function uses
guard(spinlock_irqsave)(&channel->vc.lock) inside the loop, while
goto suspend_recover and goto reset_deassert are used for error handling
outside the loop.
> +
> + if (!(channel->status & BIT(RZ_DMAC_CHAN_STATUS_CYCLIC)))
> + continue;
> +
> + ret = rz_dmac_device_pause_internal(channel);
> + if (ret) {
> + dev_err(dev, "Failed to suspend channel %s\n",
> + dma_chan_name(&channel->vc.chan));
> + break;
> + }
> +
> + channel->pm_state.nxla = rz_dmac_ch_readl(channel, NXLA, 1);
> + }
> +
> + if (ret)
> + goto suspend_recover;
> +
> + ret = reset_control_assert(dmac->rstc);
[Severity: High]
Does this logic risk a regression if an interrupt fires during or after system
suspend?
This driver implements system suspend using SIMPLE_DEV_PM_OPS, so this
function runs during the normal suspend phase where device interrupts are
still enabled. This function asserts the hardware reset and powers down the
DMA controller.
If a delayed interrupt fires concurrently on another CPU,
rz_dmac_irq_handle_channel() will execute and directly read the CHSTAT
register. Since the driver neither disables the IRQ, calls synchronize_irq(),
nor verifies the power state via pm_runtime_get_if_active(), the handler will
read from powered-off or reset hardware.
> + if (ret)
> + goto suspend_recover;
> +
> + ret = pm_runtime_put_sync(dev);
> + if (ret < 0)
> + goto reset_deassert;
[Severity: High]
Does this error path fail to properly manage the runtime PM usage counter?
pm_runtime_put_sync() unconditionally decrements the usage counter. If it
fails, the function jumps to reset_deassert and aborts system suspend without
restoring the usage counter via pm_runtime_get_noresume().
Because the system suspend is aborted, the resume callback will be skipped,
leaving the usage counter permanently decremented. Subsequent suspends could
underflow the counter and break runtime PM functionality.
> +
> + return 0;
> +
> +reset_deassert:
> + reset_control_deassert(dmac->rstc);
> +suspend_recover:
> + rz_dmac_suspend_recover(dmac);
> + return ret;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260526084710.3491480-1-claudiu.beznea@kernel.org?part=15
next prev parent reply other threads:[~2026-05-26 9:43 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-26 8:46 [PATCH v6 00/18] Renesas: dmaengine and ASoC fixes Claudiu Beznea
2026-05-26 8:46 ` [PATCH v6 01/18] dmaengine: sh: rz-dmac: Move interrupt request after everything is set up Claudiu Beznea
2026-05-26 8:54 ` Biju Das
2026-05-26 9:45 ` Claudiu Beznea
2026-05-26 9:51 ` Biju Das
2026-05-26 10:25 ` Claudiu Beznea
2026-05-26 10:39 ` Biju Das
2026-05-26 9:20 ` sashiko-bot
2026-05-28 13:44 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 02/18] dmaengine: sh: rz-dmac: Fix incorrect NULL check for list_first_entry() Claudiu Beznea
2026-05-26 9:03 ` sashiko-bot
2026-05-28 13:45 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 03/18] dmaengine: sh: rz-dmac: Use list_first_entry_or_null() Claudiu Beznea
2026-05-28 13:45 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 04/18] dmaengine: sh: rz-dmac: Use rz_dmac_disable_hw() Claudiu Beznea
2026-05-26 9:15 ` sashiko-bot
2026-05-28 13:46 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 05/18] dmaengine: sh: rz-dmac: Add helper to compute the lmdesc address Claudiu Beznea
2026-05-28 13:47 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 06/18] dmaengine: sh: rz-dmac: Save the start LM descriptor Claudiu Beznea
2026-05-26 9:41 ` sashiko-bot
2026-05-28 13:47 ` Tommaso Merciai
2026-05-26 8:46 ` [PATCH v6 07/18] dmaengine: sh: rz-dmac: Add helper to check if the channel is enabled Claudiu Beznea
2026-05-28 13:48 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 08/18] dmaengine: sh: rz-dmac: Add helper to check if the channel is paused Claudiu Beznea
2026-05-28 13:48 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 09/18] dmaengine: sh: rz-dmac: Use virt-dma APIs for channel descriptor processing Claudiu Beznea
2026-05-26 9:28 ` sashiko-bot
2026-05-28 13:49 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 10/18] dmaengine: sh: rz-dmac: Refactor pause/resume code Claudiu Beznea
2026-05-26 9:28 ` sashiko-bot
2026-05-28 13:50 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 11/18] dmaengine: sh: rz-dmac: Drop the update of channel->chctrl with CHCTRL_SETEN Claudiu Beznea
2026-05-26 9:11 ` sashiko-bot
2026-05-28 13:50 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 12/18] dmaengine: sh: rz-dmac: Add cyclic DMA support Claudiu Beznea
2026-05-26 9:31 ` sashiko-bot
2026-05-28 13:51 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 13/18] dmaengine: sh: rz-dmac: Adjust rz_dmac_chan_get_residue() to return error codes Claudiu Beznea
2026-05-28 13:51 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 14/18] dmaengine: sh: rz-dmac: Add runtime PM support Claudiu Beznea
2026-05-26 9:57 ` sashiko-bot
2026-05-28 13:52 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 15/18] dmaengine: sh: rz-dmac: Add suspend to RAM support Claudiu Beznea
2026-05-26 9:43 ` sashiko-bot [this message]
2026-05-28 14:38 ` Tommaso Merciai
2026-05-26 8:47 ` [PATCH v6 16/18] ASoC: renesas: rz-ssi: Add pause support Claudiu Beznea
2026-05-26 9:46 ` sashiko-bot
2026-05-26 8:47 ` [PATCH v6 17/18] ASoC: renesas: rz-ssi: Use generic PCM dmaengine APIs Claudiu Beznea
2026-05-26 10:00 ` sashiko-bot
2026-05-26 8:47 ` [PATCH v6 18/18] dmaengine: sh: rz-dmac: Set the Link End (LE) bit on the last descriptor Claudiu Beznea
2026-05-26 9:43 ` sashiko-bot
2026-05-28 14:39 ` Tommaso Merciai
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=20260526094311.123341F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=claudiu.beznea@kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
--cc=wsa+renesas@sang-engineering.com \
/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