ASoC: SOF: ipc4-topology: Protect pipeline free with mutex
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Fri, 27 Jan 2023 12:00:28 +0000 (14:00 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 27 Jan 2023 12:14:11 +0000 (12:14 +0000)
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: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230127120031.10709-16-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/ipc4-pcm.c
sound/soc/sof/ipc4-priv.h
sound/soc/sof/ipc4-topology.c
sound/soc/sof/ipc4.c

index ababa29d6eac1c605b5611da4c0d0da541e58a44..2d89d3708ed08e5ca15c0e03c225db0bf99025b6 100644 (file)
@@ -222,7 +222,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
        if (!trigger_list)
                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
@@ -289,7 +289,7 @@ skip_pause_transition:
        }
 
 free:
-       mutex_unlock(&ipc4_data->trigger_mutex);
+       mutex_unlock(&ipc4_data->pipeline_state_mutex);
        kfree(trigger_list);
        return ret;
 }
index 0c0d48376045e50ce43a8d7298e5d88addcb7278..38bb3d7df42e55614acc5b40aa1d780775b13192 100644 (file)
@@ -70,7 +70,7 @@ struct sof_ipc4_fw_library {
  *                 base firmware
  *
  * @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 {
        u32 manifest_fw_hdr_offset;
@@ -83,7 +83,7 @@ struct sof_ipc4_fw_data {
 
        int (*load_library)(struct snd_sof_dev *sdev,
                            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;
index 2f82b5e02a2789dd707533c11615b520c2bb9a49..43340c8917b7f7c4641e5f86ae93819d4f837301 100644 (file)
@@ -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)
 {
        struct sof_ipc4_fw_module *fw_module = swidget->module_info;
+       struct sof_ipc4_fw_data *ipc4_data = sdev->private;
        int ret = 0;
 
+       mutex_lock(&ipc4_data->pipeline_state_mutex);
+
        /* freeing a pipeline frees all the widgets associated with it */
        if (swidget->id == snd_soc_dapm_scheduler) {
                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
                ida_free(&fw_module->m_ida, swidget->instance_id);
        }
 
+       mutex_unlock(&ipc4_data->pipeline_state_mutex);
+
        return ret;
 }
 
index fb4760ae593f8c5c50a5da90e0854c8211e128b1..35c9f3913d9a4a87e3f548be843aa80de4520e88 100644 (file)
@@ -662,7 +662,7 @@ static int sof_ipc4_init(struct snd_sof_dev *sdev)
 {
        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);