Re: [PATCH v2] ASoC: generic: keep fallback dai_name stable across rebind
From: Cássio Gabriel Monteiro Pires
Date: Fri Mar 27 2026 - 01:22:46 EST
On 3/27/26 01:11, Cássio Gabriel wrote:
> simple_parse_dai() and graph_util_parse_dai() first try to identify a
> DAI via dai_args. When that works the card can rebind without relying on
> dlc->dai_name.
>
> The fallback path still calls snd_soc_get_dlc(), which returns a
> borrowed dai_name pointer. If the CPU or codec component is unbound
> while the sound card stays registered, the generic card keeps that
> pointer and the next rebind may compare stale memory while matching the
> DAI.
>
> Stage the fallback result in a temporary dai_link_component and move
> only a card-owned copy of dai_name into the live link component. Use
> devm_kstrdup_const() so static names are reused and dynamic ones remain
> valid for the lifetime of the card device.
>
> Signed-off-by: Cássio Gabriel <cassiogabrielcontato@xxxxxxxxx>
> Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx>
> ---
> Changes in v2:
> - Rework simple_parse_dai() and graph_util_parse_dai() to use if/else
> instead of a non-error goto.
> - Move the fallback snd_soc_get_dlc() handling into the else branch.
> - Link to v1: https://patch.msgid.link/20260326-asoc-generic-fallback-dai-name-rebind-v1-1-ac9da3cbd606@xxxxxxxxx
> ---
> sound/soc/generic/simple-card-utils.c | 52 ++++++++++++++++-------------------
> sound/soc/generic/simple-card.c | 46 ++++++++++++++-----------------
> 2 files changed, 44 insertions(+), 54 deletions(-)
>
> diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
> index da6353594d61..e5cb602fd248 100644
> --- a/sound/soc/generic/simple-card-utils.c
> +++ b/sound/soc/generic/simple-card-utils.c
> @@ -1128,7 +1128,9 @@ int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
> struct device *dev = simple_priv_to_dev(priv);
> struct device_node *node;
> struct of_phandle_args args = {};
> + struct snd_soc_dai_link_component resolved_dlc = {};
> struct snd_soc_dai *dai;
> + const char *fallback_dai_name;
> int ret;
>
> if (!ep)
> @@ -1152,39 +1154,31 @@ int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
> dlc->of_node = node;
> dlc->dai_name = dai_name;
> dlc->dai_args = dai_args;
> + } else {
> + /* Get dai->name */
> + args.np = node;
> + args.args[0] = graph_get_dai_id(ep);
> + args.args_count = (of_graph_get_endpoint_count(node) > 1);
>
> - goto parse_dai_end;
> - }
> + ret = snd_soc_get_dlc(&args, &resolved_dlc);
> + if (ret < 0)
> + goto err;
>
> - /* Get dai->name */
> - args.np = node;
> - args.args[0] = graph_get_dai_id(ep);
> - args.args_count = (of_graph_get_endpoint_count(node) > 1);
> + /* Keep fallback dai_name valid across component rebind */
> + fallback_dai_name = resolved_dlc.dai_name;
> + if (fallback_dai_name) {
> + fallback_dai_name = devm_kstrdup_const(dev, fallback_dai_name,
> + GFP_KERNEL);
> + ret = -ENOMEM;
> + if (!fallback_dai_name)
> + goto err;
> + }
>
> - /*
> - * FIXME
> - *
> - * Here, dlc->dai_name is pointer to CPU/Codec DAI name.
> - * If user unbinded CPU or Codec driver, but not for Sound Card,
> - * dlc->dai_name is keeping unbinded CPU or Codec
> - * driver's pointer.
> - *
> - * If user re-bind CPU or Codec driver again, ALSA SoC will try
> - * to rebind Card via snd_soc_try_rebind_card(), but because of
> - * above reason, it might can't bind Sound Card.
> - * Because Sound Card is pointing to released dai_name pointer.
> - *
> - * To avoid this rebind Card issue,
> - * 1) It needs to alloc memory to keep dai_name eventhough
> - * CPU or Codec driver was unbinded, or
> - * 2) user need to rebind Sound Card everytime
> - * if he unbinded CPU or Codec.
> - */
> - ret = snd_soc_get_dlc(&args, dlc);
> - if (ret < 0)
> - goto err;
> + dlc->of_node = resolved_dlc.of_node;
> + dlc->dai_name = fallback_dai_name;
> + dlc->dai_args = resolved_dlc.dai_args;
> + }
>
> -parse_dai_end:
> if (is_single_link)
> *is_single_link = of_graph_get_endpoint_count(node) == 1;
> ret = 0;
> diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
> index 9937a991846e..b24ba1330896 100644
> --- a/sound/soc/generic/simple-card.c
> +++ b/sound/soc/generic/simple-card.c
> @@ -69,7 +69,9 @@ static int simple_parse_dai(struct simple_util_priv *priv,
> {
> struct device *dev = simple_priv_to_dev(priv);
> struct of_phandle_args args;
> + struct snd_soc_dai_link_component resolved_dlc = {};
> struct snd_soc_dai *dai;
> + const char *fallback_dai_name;
> int ret;
>
> if (!node)
> @@ -94,34 +96,28 @@ static int simple_parse_dai(struct simple_util_priv *priv,
> dlc->dai_args = snd_soc_copy_dai_args(dev, &args);
> if (!dlc->dai_args)
> goto end;
> + } else {
> + ret = snd_soc_get_dlc(&args, &resolved_dlc);
> + if (ret < 0)
> + goto end;
>
> - goto parse_dai_end;
> - }
> + /* Keep fallback dai_name valid across component rebind */
> + fallback_dai_name = resolved_dlc.dai_name;
> + if (fallback_dai_name) {
> + fallback_dai_name = devm_kstrdup_const(dev, fallback_dai_name,
> + GFP_KERNEL);
> + ret = -ENOMEM;
> + if (!fallback_dai_name) {
> + of_node_put(resolved_dlc.of_node);
> + goto end;
> + }
> + }
>
> - /*
> - * FIXME
> - *
> - * Here, dlc->dai_name is pointer to CPU/Codec DAI name.
> - * If user unbinded CPU or Codec driver, but not for Sound Card,
> - * dlc->dai_name is keeping unbinded CPU or Codec
> - * driver's pointer.
> - *
> - * If user re-bind CPU or Codec driver again, ALSA SoC will try
> - * to rebind Card via snd_soc_try_rebind_card(), but because of
> - * above reason, it might can't bind Sound Card.
> - * Because Sound Card is pointing to released dai_name pointer.
> - *
> - * To avoid this rebind Card issue,
> - * 1) It needs to alloc memory to keep dai_name eventhough
> - * CPU or Codec driver was unbinded, or
> - * 2) user need to rebind Sound Card everytime
> - * if he unbinded CPU or Codec.
> - */
> - ret = snd_soc_get_dlc(&args, dlc);
> - if (ret < 0)
> - goto end;
> + dlc->of_node = resolved_dlc.of_node;
> + dlc->dai_name = fallback_dai_name;
> + dlc->dai_args = resolved_dlc.dai_args;
> + }
>
> -parse_dai_end:
> if (is_single_link)
> *is_single_link = !args.args_count;
> ret = 0;
>
> ---
> base-commit: d084fd53a2fd5748d4317635b1c1a7dba7edf583
> change-id: 20260326-asoc-generic-fallback-dai-name-rebind-6381a1c807fd
>
> Best regards,
> --
> Cássio Gabriel <cassiogabrielcontato@xxxxxxxxx>
>
I forgot to add the 'Suggested-by' tag attributing
the suggestion made by Kuninori. I apologize.
Should I send a v3 patch adding the tag?
--
Thanks,
Cássio