[PATCH 0/2] ASoC: SOF: ipc4-topology: fix error and memory handling
Two patches to improve error and memory handling. When IPC4 is used, some of the flows were incorrect.
Libin Yang (2): ASoC: SOF: ipc4-topology: check dai->private in ipc_free() ASoC: SOF: ipc4-topology: free memories allocated in sof_ipc4_get_audio_fmt
sound/soc/sof/ipc4-topology.c | 59 ++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-)
From: Libin Yang libin.yang@intel.com
Set the swidget->private or dai->private to NULL after kfree in the error handling in ipc_setup(). The private needs to be set NULL because if ipc_setup() returns error, ipc_free() will be called later. ipc_free() will judge the private is NULL or not to do the clearing.
For dai widget, dai->private is allocated and set in dai widget ipc_setup(). So we need to check dai->private is NULL or not in the ipc_free().
Fixes: 2cabd02b6090 ("ASoC: SOF: ipc4-topology: Add support for parsing AIF_IN/AIF_OUT widgets") Fixes: abfb536bd116 ("ASoC: SOF: ipc4-topology: Add support for parsing DAI_IN/DAI_OUT widgets") Fixes: 4f838ab20812 ("ASoC: SOF: ipc4-topology: Add support for parsing and preparing pga widgets") Fixes: 4d4ba014ac4b ("ASoC: SOF: ipc4-topology: Add support for parsing mixer widgets") Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Signed-off-by: Libin Yang libin.yang@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/sof/ipc4-topology.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 34f805431f2e..2d157ea79db5 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -394,6 +394,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) kfree(available_fmt->dma_buffer_size); free_copier: kfree(ipc4_copier); + swidget->private = NULL; return ret; }
@@ -541,6 +542,8 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) kfree(available_fmt->dma_buffer_size); free_copier: kfree(ipc4_copier); + dai->private = NULL; + dai->scomp = NULL; return ret; }
@@ -553,6 +556,12 @@ static void sof_ipc4_widget_free_comp_dai(struct snd_sof_widget *swidget) if (!dai) return;
+ if (!dai->private) { + kfree(dai); + swidget->private = NULL; + return; + } + ipc4_copier = dai->private; available_fmt = &ipc4_copier->available_fmt;
@@ -669,6 +678,7 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget) return 0; err: kfree(gain); + swidget->private = NULL; return ret; }
@@ -698,6 +708,7 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) return 0; err: kfree(mixer); + swidget->private = NULL; return ret; }
From: Libin Yang libin.yang@intel.com
Free the memories allocated in sof_ipc4_get_audio_fmt in error handling and ipc_free()
Fixes: 2cabd02b6090 ("ASoC: SOF: ipc4-topology: Add support for parsing AIF_IN/AIF_OUT widgets") Fixes: abfb536bd116 ("ASoC: SOF: ipc4-topology: Add support for parsing DAI_IN/DAI_OUT widgets") Fixes: 4f838ab20812 ("ASoC: SOF: ipc4-topology: Add support for parsing and preparing pga widgets") Fixes: 4d4ba014ac4b ("ASoC: SOF: ipc4-topology: Add support for parsing mixer widgets") Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Signed-off-by: Libin Yang libin.yang@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- sound/soc/sof/ipc4-topology.c | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 2d157ea79db5..22ea628d78d0 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -263,6 +263,16 @@ static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp, return ret; }
+/* release the memory allocated in sof_ipc4_get_audio_fmt */ +static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt) + +{ + kfree(available_fmt->base_config); + available_fmt->base_config = NULL; + kfree(available_fmt->out_audio_fmt); + available_fmt->out_audio_fmt = NULL; +} + static void sof_ipc4_widget_free_comp(struct snd_sof_widget *swidget) { kfree(swidget->private); @@ -341,7 +351,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) GFP_KERNEL); if (!available_fmt->dma_buffer_size) { ret = -ENOMEM; - goto free_copier; + goto free_available_fmt; }
ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, @@ -392,6 +402,8 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) kfree(ipc4_copier->gtw_attr); err: kfree(available_fmt->dma_buffer_size); +free_available_fmt: + sof_ipc4_free_audio_fmt(available_fmt); free_copier: kfree(ipc4_copier); swidget->private = NULL; @@ -440,7 +452,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) GFP_KERNEL); if (!available_fmt->dma_buffer_size) { ret = -ENOMEM; - goto free_copier; + goto free_available_fmt; }
ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, @@ -540,6 +552,8 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) kfree(ipc4_copier->copier_config); err: kfree(available_fmt->dma_buffer_size); +free_available_fmt: + sof_ipc4_free_audio_fmt(available_fmt); free_copier: kfree(ipc4_copier); dai->private = NULL; @@ -677,11 +691,24 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
return 0; err: + sof_ipc4_free_audio_fmt(&gain->available_fmt); kfree(gain); swidget->private = NULL; return ret; }
+static void sof_ipc4_widget_free_comp_pga(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_gain *gain = swidget->private; + + if (!gain) + return; + + sof_ipc4_free_audio_fmt(&gain->available_fmt); + kfree(swidget->private); + swidget->private = NULL; +} + static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) { struct snd_soc_component *scomp = swidget->scomp; @@ -707,11 +734,24 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
return 0; err: + sof_ipc4_free_audio_fmt(&mixer->available_fmt); kfree(mixer); swidget->private = NULL; return ret; }
+static void sof_ipc4_widget_free_comp_mixer(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_mixer *mixer = swidget->private; + + if (!mixer) + return; + + sof_ipc4_free_audio_fmt(&mixer->available_fmt); + kfree(swidget->private); + swidget->private = NULL; +} + static void sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, struct sof_ipc4_base_module_cfg *base_config) @@ -1746,11 +1786,11 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp, pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, NULL, NULL}, - [snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp, + [snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp_pga, pga_token_list, ARRAY_SIZE(pga_token_list), NULL, sof_ipc4_prepare_gain_module, sof_ipc4_unprepare_generic_module}, - [snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp, + [snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp_mixer, mixer_token_list, ARRAY_SIZE(mixer_token_list), NULL, sof_ipc4_prepare_mixer_module, sof_ipc4_unprepare_generic_module},
On Fri, 8 Jul 2022 15:05:14 -0500, Pierre-Louis Bossart wrote:
Two patches to improve error and memory handling. When IPC4 is used, some of the flows were incorrect.
Libin Yang (2): ASoC: SOF: ipc4-topology: check dai->private in ipc_free() ASoC: SOF: ipc4-topology: free memories allocated in sof_ipc4_get_audio_fmt
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/2] ASoC: SOF: ipc4-topology: check dai->private in ipc_free() commit: b737fd8cf196bc96e471304007c3cd9b78672069 [2/2] ASoC: SOF: ipc4-topology: free memories allocated in sof_ipc4_get_audio_fmt commit: dc4fc0ae94cf87f1017f158b6fa2b7536ef29b4e
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Pierre-Louis Bossart