[PATCH] ALSA: pcm: Serialize snd_pcm_suspend_all() with open_mutex

From: Cássio Gabriel

Date: Fri Mar 20 2026 - 13:29:34 EST


snd_pcm_suspend_all() walks all PCM substreams and uses a lockless
runtime check to skip closed streams. It then calls snd_pcm_suspend()
for each remaining substream and finally runs snd_pcm_sync_stop() in a
second pass.

The runtime lifetime is still controlled by pcm->open_mutex in the
open/release path. That means a concurrent close can clear or free
substream->runtime after the initial check in snd_pcm_suspend_all(),
leaving the later suspend or sync-stop path to dereference a stale or
NULL runtime pointer.

Serialize snd_pcm_suspend_all() with pcm->open_mutex so the runtime
pointer stays stable across both loops. This matches the existing PCM
runtime lifetime rule already used by other core paths that access
substream->runtime outside the stream lock.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@xxxxxxxxx>
---
sound/core/pcm_native.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 674b50c7c5f6..ebcb62603d49 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1792,8 +1792,9 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
if (! pcm)
return 0;

+ guard(mutex)(&pcm->open_mutex);
+
for_each_pcm_substream(pcm, stream, substream) {
- /* FIXME: the open/close code should lock this as well */
if (!substream->runtime)
continue;


---
base-commit: b3c48fa1fb397b490101785ddd87caf2e5513a66
change-id: 20260320-alsa-pcm-suspend-open-close-lock-56907d40df44

Best regards,
--
Cássio Gabriel <cassiogabrielcontato@xxxxxxxxx>