Commit 6bc4d1b7 authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown

ASoC: SOF: ipc4-topology: Protect pipeline free with mutex

When starting/stopping multiple streams in parallel, pipeline triggers
and pipeline frees can get interleaved. So use the same mutex used for
pipeline trigger to protect the pipeline frees as well. Rename the
trigger_mutex to pipeline_state_mutex for more clarity.
Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230127120031.10709-16-peter.ujfalusi@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 32c4b698
...@@ -222,7 +222,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, ...@@ -222,7 +222,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
if (!trigger_list) if (!trigger_list)
return -ENOMEM; return -ENOMEM;
mutex_lock(&ipc4_data->trigger_mutex); mutex_lock(&ipc4_data->pipeline_state_mutex);
/* /*
* IPC4 requires pipelines to be triggered in order starting at the sink and * IPC4 requires pipelines to be triggered in order starting at the sink and
...@@ -289,7 +289,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, ...@@ -289,7 +289,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
} }
free: free:
mutex_unlock(&ipc4_data->trigger_mutex); mutex_unlock(&ipc4_data->pipeline_state_mutex);
kfree(trigger_list); kfree(trigger_list);
return ret; return ret;
} }
......
...@@ -70,7 +70,7 @@ struct sof_ipc4_fw_library { ...@@ -70,7 +70,7 @@ struct sof_ipc4_fw_library {
* base firmware * base firmware
* *
* @load_library: Callback function for platform dependent library loading * @load_library: Callback function for platform dependent library loading
* @trigger_mutex: Mutex to protect pipeline triggers, ref counts and states * @pipeline_state_mutex: Mutex to protect pipeline triggers, ref counts, states and deletion
*/ */
struct sof_ipc4_fw_data { struct sof_ipc4_fw_data {
u32 manifest_fw_hdr_offset; u32 manifest_fw_hdr_offset;
...@@ -83,7 +83,7 @@ struct sof_ipc4_fw_data { ...@@ -83,7 +83,7 @@ struct sof_ipc4_fw_data {
int (*load_library)(struct snd_sof_dev *sdev, int (*load_library)(struct snd_sof_dev *sdev,
struct sof_ipc4_fw_library *fw_lib, bool reload); struct sof_ipc4_fw_library *fw_lib, bool reload);
struct mutex trigger_mutex; /* protect pipeline triggers, ref counts and states */ struct mutex pipeline_state_mutex; /* protect pipeline triggers, ref counts and states */
}; };
extern const struct sof_ipc_fw_loader_ops ipc4_loader_ops; extern const struct sof_ipc_fw_loader_ops ipc4_loader_ops;
......
...@@ -1625,8 +1625,11 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget ...@@ -1625,8 +1625,11 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
{ {
struct sof_ipc4_fw_module *fw_module = swidget->module_info; struct sof_ipc4_fw_module *fw_module = swidget->module_info;
struct sof_ipc4_fw_data *ipc4_data = sdev->private;
int ret = 0; int ret = 0;
mutex_lock(&ipc4_data->pipeline_state_mutex);
/* freeing a pipeline frees all the widgets associated with it */ /* freeing a pipeline frees all the widgets associated with it */
if (swidget->id == snd_soc_dapm_scheduler) { if (swidget->id == snd_soc_dapm_scheduler) {
struct sof_ipc4_pipeline *pipeline = swidget->private; struct sof_ipc4_pipeline *pipeline = swidget->private;
...@@ -1652,6 +1655,8 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget ...@@ -1652,6 +1655,8 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget
ida_free(&fw_module->m_ida, swidget->instance_id); ida_free(&fw_module->m_ida, swidget->instance_id);
} }
mutex_unlock(&ipc4_data->pipeline_state_mutex);
return ret; return ret;
} }
......
...@@ -662,7 +662,7 @@ static int sof_ipc4_init(struct snd_sof_dev *sdev) ...@@ -662,7 +662,7 @@ static int sof_ipc4_init(struct snd_sof_dev *sdev)
{ {
struct sof_ipc4_fw_data *ipc4_data = sdev->private; struct sof_ipc4_fw_data *ipc4_data = sdev->private;
mutex_init(&ipc4_data->trigger_mutex); mutex_init(&ipc4_data->pipeline_state_mutex);
xa_init_flags(&ipc4_data->fw_lib_xa, XA_FLAGS_ALLOC); xa_init_flags(&ipc4_data->fw_lib_xa, XA_FLAGS_ALLOC);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment