[alsa-devel] [PATCH] ASoC: soc-core: call snd_soc_unbind_card() under mutex_lock;
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
commit 34ac3c3eb8f0c07 ("ASoC: core: lock client_mutex while removing link components") added mutex_lock() at soc_remove_link_components().
Is is called from snd_soc_unbind_card()
snd_soc_unbind_card() => soc_remove_link_components() soc_cleanup_card_resources() soc_remove_dai_links() => soc_remove_link_components()
And, there are 2 way to call it.
(1) snd_soc_unregister_component() ** mutex_lock() snd_soc_component_del_unlocked() => snd_soc_unbind_card() ** mutex_unlock()
(2) snd_soc_unregister_card() => snd_soc_unbind_card()
(1) case is already using mutex_lock() when it calles snd_soc_unbind_card(), thus, we will get lockdep warning. We need mutex_lock() under snd_soc_unregister_card() instead of snd_remove_link_components().
Fixes: 34ac3c3eb8f0c07 ("ASoC: core: lock client_mutex while removing link components") Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 94a36ee..1679990 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1018,14 +1018,12 @@ static void soc_remove_link_components(struct snd_soc_card *card, struct snd_soc_component *component; struct snd_soc_rtdcom_list *rtdcom;
- mutex_lock(&client_mutex); for_each_rtdcom(rtd, rtdcom) { component = rtdcom->component;
if (component->driver->remove_order == order) soc_remove_component(component); } - mutex_unlock(&client_mutex); }
static void soc_remove_dai_links(struct snd_soc_card *card) @@ -2774,7 +2772,9 @@ static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister) */ int snd_soc_unregister_card(struct snd_soc_card *card) { + mutex_lock(&client_mutex); snd_soc_unbind_card(card, true); + mutex_unlock(&client_mutex); dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
return 0;
On Mon, 2019-06-10 at 09:49 +0900, Kuninori Morimoto wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
commit 34ac3c3eb8f0c07 ("ASoC: core: lock client_mutex while removing link components") added mutex_lock() at soc_remove_link_components().
Is is called from snd_soc_unbind_card()
snd_soc_unbind_card() => soc_remove_link_components() soc_cleanup_card_resources() soc_remove_dai_links() => soc_remove_link_components()
And, there are 2 way to call it.
(1) snd_soc_unregister_component() ** mutex_lock() snd_soc_component_del_unlocked() => snd_soc_unbind_card() ** mutex_unlock()
(2) snd_soc_unregister_card() => snd_soc_unbind_card()
(1) case is already using mutex_lock() when it calles snd_soc_unbind_card(), thus, we will get lockdep warning. We need mutex_lock() under snd_soc_unregister_card() instead of snd_remove_link_components().
Thanks, Morimoto-san. I submitted a solution to fix the deadlock just a couple of days ago as well ( https://mailman.alsa-project.org/pipermail/alsa-devel/2019-June/150764.html ).
I am fine with either solution though.
Thanks, Ranjani
Fixes: 34ac3c3eb8f0c07 ("ASoC: core: lock client_mutex while removing link components") Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
sound/soc/soc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 94a36ee..1679990 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1018,14 +1018,12 @@ static void soc_remove_link_components(struct snd_soc_card *card, struct snd_soc_component *component; struct snd_soc_rtdcom_list *rtdcom;
mutex_lock(&client_mutex); for_each_rtdcom(rtd, rtdcom) { component = rtdcom->component;
if (component->driver->remove_order == order) soc_remove_component(component); }
mutex_unlock(&client_mutex);
}
static void soc_remove_dai_links(struct snd_soc_card *card) @@ -2774,7 +2772,9 @@ static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister) */ int snd_soc_unregister_card(struct snd_soc_card *card) {
- mutex_lock(&client_mutex); snd_soc_unbind_card(card, true);
- mutex_unlock(&client_mutex); dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card-
name);
return 0;
Hi Ranjani
Thank you for your feedback
Thanks, Morimoto-san. I submitted a solution to fix the deadlock just a couple of days ago as well ( https://mailman.alsa-project.org/pipermail/alsa-devel/2019-June/150764.html ).
I am fine with either solution though.
Hmm... If my understanding was correct, mutex_lock under snd_soc_unbind_card() is not good / not enough. My patch can solve these, but please double check it.
# To be honest, current ALSA SoC is very difficult to read. # Thus, I'm working to cleanup code, actually. I want to post it. # I'm waiting for posted patches to be applied
1) snd_soc_unbind_card() is used from snd_soc_component_del_unlocked() which is used from __snd_soc_unregister_component(). It is using mutex_lock() already
__snd_soc_unregister_component() => mutex_lock() snd_soc_component_del_unlocked() snd_soc_unbind_card() => mutex_lock() soc_remove_link_components() => mutex_unlock() (*2) soc_cleanup_card_resources() => mutex_unlock()
(2) soc_cleanup_card_resources() also calls soc_remove_link_components() (see above (*2))
soc_cleanup_card_resources() soc_remove_dai_links() => soc_remove_link_components()
participants (2)
-
Kuninori Morimoto
-
Ranjani Sridharan