2023-09-20 15:48:55

by Chancel Liu

[permalink] [raw]
Subject: [PATCH v2 1/1] ASoC: soc-pcm.c: Make sure DAI parameters cleared if the DAI becomes inactive

The commit 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs parameters after
stream_active is updated") tries to make sure DAI parameters can be
cleared properly through moving the cleanup to the place where stream
active status is updated. However, it will cause the cleanup only
happening in soc_pcm_close().

Suppose a case: aplay -Dhw:0 44100.wav 48000.wav. The case calls
soc_pcm_open()->soc_pcm_hw_params()->soc_pcm_hw_free()->
soc_pcm_hw_params()->soc_pcm_hw_free()->soc_pcm_close() in order. The
parameters would be remained in the system even if the playback of
44100.wav is finished.

The case requires us clearing parameters in phase of soc_pcm_hw_free().
However, moving the DAI parameters cleanup back to soc_pcm_hw_free()
has the risk that DAIs parameters never be cleared if there're more
than one stream, see commit 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs
parameters after stream_active is updated") for more details.

To meet all these requirements, in addition to do DAI parameters
cleanup in soc_pcm_hw_free(), also check it in soc_pcm_close() to make
sure DAI parameters cleared if the DAI becomes inactive.

Fixes: 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs parameters after stream_active is updated")
Signed-off-by: Chancel Liu <[email protected]>
---
sound/soc/soc-pcm.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 3aa6b988cb4b..6cf4cd667d03 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -698,14 +698,12 @@ static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd,

if (!rollback) {
snd_soc_runtime_deactivate(rtd, substream->stream);
- /* clear the corresponding DAIs parameters when going to be inactive */
- for_each_rtd_dais(rtd, i, dai) {
- if (snd_soc_dai_active(dai) == 0)
- soc_pcm_set_dai_params(dai, NULL);

- if (snd_soc_dai_stream_active(dai, substream->stream) == 0)
- snd_soc_dai_digital_mute(dai, 1, substream->stream);
- }
+ /* Make sure DAI parameters cleared if the DAI becomes inactive */
+ for_each_rtd_dais(rtd, i, dai)
+ if (snd_soc_dai_active(dai) == 0 &&
+ (dai->rate || dai->channels || dai->sample_bits))
+ soc_pcm_set_dai_params(dai, NULL);
}

for_each_rtd_dais(rtd, i, dai)
@@ -936,6 +934,15 @@ static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd,

snd_soc_dpcm_mutex_assert_held(rtd);

+ /* clear the corresponding DAIs parameters when going to be inactive */
+ for_each_rtd_dais(rtd, i, dai) {
+ if (snd_soc_dai_active(dai) == 1)
+ soc_pcm_set_dai_params(dai, NULL);
+
+ if (snd_soc_dai_stream_active(dai, substream->stream) == 1)
+ snd_soc_dai_digital_mute(dai, 1, substream->stream);
+ }
+
/* run the stream event */
snd_soc_dapm_stream_stop(rtd, substream->stream);

--
2.25.1


2023-11-27 08:29:14

by Johan Hovold

[permalink] [raw]
Subject: Re: [PATCH v2 1/1] ASoC: soc-pcm.c: Make sure DAI parameters cleared if the DAI becomes inactive

On Wed, Sep 20, 2023 at 11:36:21PM +0800, Chancel Liu wrote:
> The commit 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs parameters after
> stream_active is updated") tries to make sure DAI parameters can be
> cleared properly through moving the cleanup to the place where stream
> active status is updated. However, it will cause the cleanup only
> happening in soc_pcm_close().
>
> Suppose a case: aplay -Dhw:0 44100.wav 48000.wav. The case calls
> soc_pcm_open()->soc_pcm_hw_params()->soc_pcm_hw_free()->
> soc_pcm_hw_params()->soc_pcm_hw_free()->soc_pcm_close() in order. The
> parameters would be remained in the system even if the playback of
> 44100.wav is finished.
>
> The case requires us clearing parameters in phase of soc_pcm_hw_free().
> However, moving the DAI parameters cleanup back to soc_pcm_hw_free()
> has the risk that DAIs parameters never be cleared if there're more
> than one stream, see commit 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs
> parameters after stream_active is updated") for more details.
>
> To meet all these requirements, in addition to do DAI parameters
> cleanup in soc_pcm_hw_free(), also check it in soc_pcm_close() to make
> sure DAI parameters cleared if the DAI becomes inactive.
>
> Fixes: 1da681e52853 ("ASoC: soc-pcm.c: Clear DAIs parameters after stream_active is updated")
> Signed-off-by: Chancel Liu <[email protected]>

For the record, this change incidentally also fixed the remaining click
sounds I heard when stopping pulseaudio (e.g. on reboot) with the Lenovo
ThinkPad X13s, which have also been discussed here:

https://lore.kernel.org/lkml/[email protected]/

Johan