All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: phucduc.bui@gmail.com
Cc: devicetree@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org,
	wsa+renesas@sang-engineering.com
Subject: Re: [PATCH v5 10/11] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()
Date: Tue, 09 Jun 2026 01:51:02 +0000	[thread overview]
Message-ID: <20260609015102.9E7E61F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260609013107.5995-11-phucduc.bui@gmail.com>

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

New issues:
- [High] The interrupt handler `fsi_interrupt` reads and writes hardware registers before verifying if any streams are active, risking system hangs.

Pre-existing issues:
- [High] `fsi_clk_enable()` incorrectly returns `-EINVAL` and improperly manages `clock->count` when a second concurrent stream is started, breaking full-duplex operation.
- [High] The driver calls `clk_set_rate` and `clk_set_parent` from the atomic PCM trigger callback, causing a 'scheduling while atomic' bug.
- [High] Opening or closing a stream resets the shared clock rate via `fsi_clk_invalid()`, corrupting the state of an already running concurrent stream and causing permanent clock reference leaks.
- [High] Lockless access to the shared `clock->count` variable leads to race conditions and unbalanced clock reference counts when playback and capture are triggered concurrently.
--

commit f7c3ccc68e9715cc648ab7fe51a1667d7610390b
Author: bui duc phuc <phucduc.bui@gmail.com>

ASoC: renesas: fsi: add fsi_clk_prepare/unprepare()

Add fsi_clk_prepare() and fsi_clk_unprepare() helpers and call them
from fsi_dai_startup() and fsi_dai_shutdown(). This ensures clk_prepare()
and clk_unprepare() are executed from sleepable contexts and keeps clocks
prepared only while audio streams are active.

> diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
> index 6c432c7235a41..80e87b815c1b6 100644
> --- a/sound/soc/renesas/fsi.c
> +++ b/sound/soc/renesas/fsi.c
> @@ -730,6 +730,54 @@ static int fsi_clk_is_valid(struct fsi_priv *fsi)
>  		fsi->clock.rate;
>  }
>  
> +static int fsi_clk_prepare(struct fsi_priv *fsi)
[ ... ]
> +static void fsi_clk_unprepare(struct fsi_priv *fsi)
[ ... ]
> +}
> +
>  static int fsi_clk_enable(struct device *dev,
>  			  struct fsi_priv *fsi)
>  {

[Severity: High]
This is a pre-existing issue, but does fsi_clk_enable() break when a second
concurrent stream is started?

In fsi_clk_enable():

	int ret = -EINVAL;

	if (!fsi_clk_is_valid(fsi))
		return ret;

	if (0 == clock->count) {
		...
	}

	return ret;

If clock->count > 0, such as when starting a capture stream while playback is
already active, the zero check is skipped entirely. The function then returns
the unassigned ret (-EINVAL), causing the ALSA trigger callback to fail.

[Severity: High]
This isn't a bug introduced by this patch, but does fsi_clk_enable() cause a
"scheduling while atomic" bug?

The ALSA fsi_dai_trigger() callback executes in an atomic context with the PCM
substream spinlock held and interrupts disabled. On a START trigger, it calls
fsi_hw_startup(), which invokes fsi_clk_enable():

	if (0 == clock->count) {
		ret = clock->set_rate(dev, fsi);

The clock->set_rate() functions invoke clk_set_rate() and clk_set_parent(),
which acquire the clk_prepare_lock mutex and can sleep.

Calling them from an atomic context causes a BUG. While this patch moves
clk_prepare() to the sleepable startup callback, rate setting remains in the
atomic trigger path.

[Severity: High]
This is a pre-existing issue, but could lockless access to the shared
clock->count variable lead to race conditions?

The fsi_priv struct and its clock->count member are shared between playback
and capture substreams on the same DAI. ALSA PCM trigger callbacks are
serialized per-substream, not per-DAI, allowing playback and capture triggers
to execute concurrently.

fsi_clk_enable() checks if count is zero and increments it without any
locking. If both streams start concurrently, both CPUs can observe count == 0,
execute the clk_enable logic simultaneously, and increment count to 2, but
clk_enable() was called twice for each clock.

When stopping, fsi_clk_disable() uses `if (1 == clock->count--)`. The first
stop drops count from 2 to 1 and does not call clk_disable(). The second stop
drops count from 1 to 0 and calls clk_disable() once. This leaves the clock
enable counts permanently unbalanced by +1.

> @@ -1580,7 +1628,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
>  
>  	fsi_clk_invalid(fsi);

[Severity: High]
This is a pre-existing issue, but does calling fsi_clk_invalid() here corrupt
the state of concurrent active streams?

Because fsi_priv is shared between playback and capture, opening a new stream
while another is actively running overwrites the operating stream's clock rate
to 0.

When the active stream is eventually stopped, fsi_hw_shutdown() calls
fsi_clk_disable(). Because fsi_clk_is_valid() relies on the now zeroed
clock->rate, it evaluates to false.

This causes fsi_clk_disable() to return -EINVAL immediately without
decrementing clock->count or disabling the hardware clocks, resulting in a
permanent clock enable leak.

>  
> -	return 0;
> +	return fsi_clk_prepare(fsi);
>  }
>  
>  static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
> @@ -1588,6 +1636,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
>  {
>  	struct fsi_priv *fsi = fsi_get_priv(substream);
>  
> +	fsi_clk_unprepare(fsi);

[Severity: High]
Could unpreparing the clock here risk a system hang in the interrupt handler?

If an in-flight or spurious IRQ fires after streams are shut down, the
fsi_interrupt() handler executes. If the SPU clock is disabled, the handler
immediately accesses hardware registers before verifying if any streams are
active:

    u32 int_st = fsi_irq_get_status(master);

    /* clear irq status */
    fsi_master_mask_set(master, SOFT_RST, IR, 0);
    fsi_master_mask_set(master, SOFT_RST, IR, IR);

Accessing INT_ST and SOFT_RST registers with the SPU clock gated will cause
the system to hang.

>  	fsi_clk_invalid(fsi);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260609013107.5995-1-phucduc.bui@gmail.com?part=10

  reply	other threads:[~2026-06-09  1:51 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09  1:30 [PATCH v5 00/11] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
2026-06-09  1:30 ` [PATCH v5 01/11] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
2026-06-09  1:41   ` sashiko-bot
2026-06-09  6:54   ` Krzysztof Kozlowski
2026-06-09  8:11     ` Bui Duc Phuc
2026-06-09  8:17       ` Krzysztof Kozlowski
2026-06-09  8:42         ` Bui Duc Phuc
2026-06-09  8:54           ` Krzysztof Kozlowski
2026-06-09  9:05             ` Bui Duc Phuc
2026-06-09  1:30 ` [PATCH v5 02/11] ARM: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
2026-06-09  1:30 ` [PATCH v5 03/11] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
2026-06-09  1:43   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 04/11] ASoC: renesas: fsi: Move fsi_stream_is_working() phucduc.bui
2026-06-09  1:44   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 05/11] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
2026-06-09  1:59   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 06/11] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
2026-06-09  1:46   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 07/11] ASoC: renesas: fsi: Use devm_clk_get_optional() for optional clocks phucduc.bui
2026-06-09  1:31 ` [PATCH v5 08/11] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
2026-06-09  1:43   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 09/11] ASoC: renesas: fsi: Add SPU clock support phucduc.bui
2026-06-09  1:47   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 10/11] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
2026-06-09  1:51   ` sashiko-bot [this message]
2026-06-09  1:31 ` [PATCH v5 11/11] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
2026-06-09  1:50   ` sashiko-bot
2026-06-09  6:57 ` [PATCH v5 00/11] ASoC: renesas: fsi: Fix system hang by adding SPU clock Kuninori Morimoto
2026-06-09  9:49   ` Bui Duc Phuc

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=20260609015102.9E7E61F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=phucduc.bui@gmail.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --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 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.