Re: [PATCH] ALSA: pcm: Keep linked drain wait entries safe across unlink

From: Takashi Iwai

Date: Thu Oct 15 2026 - 14:55:48 EST


On Thu, 15 Oct 2026 19:10:29 +0200,
Cen Zhang wrote:
>
> snd_pcm_drain() queues an on-stack wait entry on a linked playback
> peer's runtime->sleep. After sleeping, it calls finish_wait() only if
> that runtime is still found in the caller's group, since the peer may
> otherwise have been freed.
>
> Unlink wakes the group members before removing them, but the generic
> autoremove_wake_function() removes an entry only when the wake succeeds.
> If a signal or timeout has already made the drainer runnable, the entry
> can remain queued after unlink. With unlink performed before DROP at
> final close, the following ordering is possible:
>
> Drainer on A Final close of linked B
> ------------ -----------------------
> Queue stack wait on B->sleep
> Signal wakes A: TASK_RUNNING
> snd_pcm_unlink(B)
> Wake returns 0; wait stays queued
> Remove B from the group
> Cannot find B; skip finish_wait()
> Return due to the pending signal
> snd_pcm_drop(B)
> Wake traverses the stale wait
>
> Use a drain-specific wake function that removes the entry under the
> waitqueue lock even when the task is already runnable. Preserve the
> ordinary wake result. This lets unlink detach the stack entry before
> changing membership, while keeping the runtime check around finish_wait()
> so drain does not access a freed peer.
>
> Also hold the existing group lock from selecting the peer through
> reading its runtime fields and queuing the wait. Releasing it before
> registration lets unlink perform its wake before the entry is queued,
> and can let the peer runtime be freed before it is accessed. Release
> the group lock after registration and on the no-peer exit path.
>
> Fixes: f57f3df03a8e ("ALSA: pcm: More fine-grained PCM link locking")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Cen Zhang <zzzccc427@xxxxxxxxx>

This doesn't look needed / fitting for the latest code?


Takashi