[PATCH] ASoC: soc-pcm: Fix DPCM lockdep warning due to nested stream locks

Takashi Iwai tiwai at suse.de
Thu Jan 13 17:12:12 CET 2022


On Thu, 13 Jan 2022 15:59:31 +0100,
Marek Szyprowski wrote:
> 
> On 13.01.2022 15:18, Takashi Iwai wrote:
> > The recent change for DPCM locking caused spurious lockdep warnings.
> > Actually the warnings are false-positive, as those are triggered due
> > to the nested stream locks for FE and BE.  Since both locks belong to
> > the same lock class, lockdep sees it as if a deadlock.
> >
> > For fixing this, we need take PCM stream locks for BE with the nested
> > lock primitives.  Since currently snd_pcm_stream_lock*() helper
> > assumes only the top-level single locking, a new helper function
> > snd_pcm_stream_lock_irqsave_nested() is defined for a single-depth
> > nested lock, which is now used in the BE DAI trigger that is always
> > performed inside a FE stream lock.
> >
> > Fixes: b7898396f4bb ("ASoC: soc-pcm: Fix and cleanup DPCM locking")
> > Reported-and-tested-by: Hans de Goede <hdegoede at redhat.com>
> > Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
> > Link: https://lore.kernel.org/r/73018f3c-9769-72ea-0325-b3f8e2381e30@redhat.com
> > Link: https://lore.kernel.org/alsa-devel/9a0abddd-49e9-872d-2f00-a1697340f786@samsung.com
> > Signed-off-by: Takashi Iwai <tiwai at suse.de>
> 
> Thanks for the fix! It helps a bit, but I still get a warning (a 
> different one now):

Thanks for the quick testing.  Actually we do have multiple issues.

> root at target:~# speaker-test -l1
> 
> speaker-test 1.1.8
> 
> Playback device is default
> Stream parameters are 48000Hz, S16_LE, 1 channels
> Using 16 octaves of pink noise
> Rate set to 48000Hz (requested 48000Hz)
> Buffer size range from 128 to 131072
> Period size range from 64 to 65536
> Using max buffer size 131072
> Periods = 4
> was set period_size = 32768
> was set buffer_size = 131072
>   0 - Front Left
> Time per period = 0.022199
> max98090 1-0010: PLL unlocked
> 
> =====================================================
> WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected
> 5.16.0-next-20220113-00001-g3967460dbcf4 #11212 Not tainted
> -----------------------------------------------------
> speaker-test/1319 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
> c1296410 (pin_fs_lock){+.+.}-{2:2}, at: simple_pin_fs+0x1c/0xac
> 
> and this task is already holding:
> c2fe6ea4 (&group->lock){..-.}-{2:2}, at: dpcm_be_disconnect+0x3c/0x348
> which would create a new lock dependency:
>   (&group->lock){..-.}-{2:2} -> (pin_fs_lock){+.+.}-{2:2}

So that's the problem: we call debugfs_remove_recursive() in the
spinlocked context.

Could you try the patch below?  It's a bit hackish, but let's check
whether that's the real cause or not.


Takashi

---
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1268,6 +1268,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
 void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm, *d;
+	LIST_HEAD(deleted_dpcms);
 
 	snd_soc_dpcm_mutex_assert_held(fe);
 
@@ -1287,13 +1288,18 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
 		/* BEs still alive need new FE */
 		dpcm_be_reparent(fe, dpcm->be, stream);
 
-		dpcm_remove_debugfs_state(dpcm);
-
 		list_del(&dpcm->list_be);
+		list_move(&dpcm->list_fe, &deleted_dpcms);
+	}
+	snd_soc_dpcm_stream_unlock_irq(fe, stream);
+
+	while (!list_empty(&deleted_dpcms)) {
+		dpcm = list_first_entry(&deleted_dpcms, struct snd_soc_dpcm,
+					list_fe);
 		list_del(&dpcm->list_fe);
+		dpcm_remove_debugfs_state(dpcm);
 		kfree(dpcm);
 	}
-	snd_soc_dpcm_stream_unlock_irq(fe, stream);
 }
 
 /* get BE for DAI widget and stream */


More information about the Alsa-devel mailing list