]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: SOF: sof-audio: Fix error path in sof_widget_setup_unlocked()
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Thu, 30 Jul 2026 08:59:14 +0000 (11:59 +0300)
committerMark Brown <broonie@kernel.org>
Thu, 30 Jul 2026 23:08:07 +0000 (00:08 +0100)
If either tplg_ops->dai_config or widget_kcontrol_setup fail during widget
setup we would double decrement the use_count of the widget because the
sof_widget_free_unlocked() would be called twice, similarly the core_put
would be invoked twice as well.

Since the use_count and core_put() is handled within the widget_free
function we need to return without falling through the pipe_widget_free
label.

The fixes tag is picked to the last change around this part of the code
which is adequately old enough for backporting purposes.

Link: https://github.com/thesofproject/sof/issues/10826
Fixes: 31ed8da1c8e5 ("ASoC: SOF: sof-audio: Modify logic for enabling/disabling topology cores")
Cc: stable@vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://patch.msgid.link/20260730085914.27546-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/sof-audio.c

index acf56607bc9c11aea0b7bac4aa1bb54e636c683a..24614e50601932eea4b2859832b633a312af409c 100644 (file)
@@ -146,7 +146,6 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
 {
        const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
        struct snd_sof_pipeline *spipe = swidget->spipe;
-       bool use_count_decremented = false;
        int ret;
        int i;
 
@@ -225,9 +224,10 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
        return 0;
 
 widget_free:
-       /* widget use_count will be decremented by sof_widget_free() */
+       /* widget use_count and core_put handled by sof_widget_free() */
        sof_widget_free_unlocked(sdev, swidget);
-       use_count_decremented = true;
+       return ret;
+
 pipe_widget_free:
        if (swidget->id != snd_soc_dapm_scheduler) {
                sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget);
@@ -242,8 +242,7 @@ pipe_widget_free:
                }
        }
 use_count_dec:
-       if (!use_count_decremented)
-               swidget->use_count--;
+       swidget->use_count--;
 
        return ret;
 }