Skip to content

Commit 20d9fde

Browse files
morimotobroonie
authored andcommitted
ASoC: soc-core: add snd_soc_find_dai_with_mutex()
commit 2561247 ("ASoC: soc-dai: set dai_link dpcm_ flags with a helper") added snd_soc_dai_link_set_capabilities(). But it is using snd_soc_find_dai() (A) which is required client_mutex (B). And client_mutex is soc-core.c local. struct snd_soc_dai *snd_soc_find_dai(xxx) { ... (B) lockdep_assert_held(&client_mutex); ... } void snd_soc_dai_link_set_capabilities(xxx) { ... for_each_pcm_streams(direction) { ... for_each_link_cpus(dai_link, i, cpu) { (A) dai = snd_soc_find_dai(cpu); ... } ... for_each_link_codecs(dai_link, i, codec) { (A) dai = snd_soc_find_dai(codec); ... } } ... } Because of these background, we will get WARNING if .config has CONFIG_LOCKDEP. WARNING: CPU: 2 PID: 53 at sound/soc/soc-core.c:814 snd_soc_find_dai+0xf8/0x100 CPU: 2 PID: 53 Comm: kworker/2:1 Not tainted 5.7.0-rc1+ torvalds#328 Hardware name: Renesas H3ULCB Kingfisher board based on r8a77951 (DT) Workqueue: events deferred_probe_work_func pstate: 60000005 (nZCv daif -PAN -UAO) pc : snd_soc_find_dai+0xf8/0x100 lr : snd_soc_find_dai+0xf4/0x100 ... Call trace: snd_soc_find_dai+0xf8/0x100 snd_soc_dai_link_set_capabilities+0xa0/0x16c graph_dai_link_of_dpcm+0x390/0x3c0 graph_for_each_link+0x134/0x200 graph_probe+0x144/0x230 platform_drv_probe+0x5c/0xb0 really_probe+0xe4/0x430 driver_probe_device+0x60/0xf4 snd_soc_find_dai() will be used from (X) CPU/Codec/Platform driver with mutex lock, and (Y) Card driver without mutex lock. This snd_soc_dai_link_set_capabilities() is for Card driver, this means called without mutex. This patch adds snd_soc_find_dai_with_mutex() to solve it. Fixes: 2561247 ("ASoC: soc-dai: set dai_link dpcm_ flags with a helper") Signed-off-by: Kuninori Morimoto <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent d563b6c commit 20d9fde

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

include/sound/soc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,8 @@ void snd_soc_unregister_dai(struct snd_soc_dai *dai);
13611361

13621362
struct snd_soc_dai *snd_soc_find_dai(
13631363
const struct snd_soc_dai_link_component *dlc);
1364+
struct snd_soc_dai *snd_soc_find_dai_with_mutex(
1365+
const struct snd_soc_dai_link_component *dlc);
13641366

13651367
#include <sound/soc-dai.h>
13661368

sound/soc/soc-core.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,19 @@ struct snd_soc_dai *snd_soc_find_dai(
834834
}
835835
EXPORT_SYMBOL_GPL(snd_soc_find_dai);
836836

837+
struct snd_soc_dai *snd_soc_find_dai_with_mutex(
838+
const struct snd_soc_dai_link_component *dlc)
839+
{
840+
struct snd_soc_dai *dai;
841+
842+
mutex_lock(&client_mutex);
843+
dai = snd_soc_find_dai(dlc);
844+
mutex_unlock(&client_mutex);
845+
846+
return dai;
847+
}
848+
EXPORT_SYMBOL_GPL(snd_soc_find_dai_with_mutex);
849+
837850
static int soc_dai_link_sanity_check(struct snd_soc_card *card,
838851
struct snd_soc_dai_link *link)
839852
{

sound/soc/soc-dai.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,14 +412,14 @@ void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
412412
supported_codec = false;
413413

414414
for_each_link_cpus(dai_link, i, cpu) {
415-
dai = snd_soc_find_dai(cpu);
415+
dai = snd_soc_find_dai_with_mutex(cpu);
416416
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
417417
supported_cpu = true;
418418
break;
419419
}
420420
}
421421
for_each_link_codecs(dai_link, i, codec) {
422-
dai = snd_soc_find_dai(codec);
422+
dai = snd_soc_find_dai_with_mutex(codec);
423423
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
424424
supported_codec = true;
425425
break;

0 commit comments

Comments
 (0)