From: sashiko-bot@kernel.org
To: "Joonho Lee" <mynameisjune111@gmail.com>, linux-sound@vger.kernel.org
Cc: virtualization@lists.linux.dev,
"Michael S. Tsirkin" <mst@redhat.com>,
"Eugenio Perez" <eperezma@redhat.com>
Subject: Re: [PATCH v7 15/16] ALSA: pcm: synchronize stopped paused streams
Date: Wed, 28 Oct 2026 10:21:37 +0000 [thread overview]
Message-ID: <sashiko-outbox-187743@kernel.org> (raw)
In-Reply-To: <20261028094132.20364-16-mynameisjune111@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] ALSA: pcm: snd_pcm_do_stop() arms sync_stop on paused streams without STOP trigger
--
commit 9cef4af5ba9c6105fe851ee2ad98ad262f35643e
Author: Joonho Lee <mynameisjune111@gmail.com>
ALSA: pcm: synchronize stopped paused streams
This commit marks runtime->stop_operating = true in snd_pcm_do_stop() when
a PCM substream is in SNDRV_PCM_STATE_PAUSED so that subsequent prepare or
drop operations invoke sync_stop to drain outstanding DMA requests.
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index a2ea44c3c1d29..ac2e5c2ee5065 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -1611,6 +1611,9 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
> substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
> substream->runtime->stop_operating = true;
> }
> + /* Paused DMA can still own requests which sync_stop must drain. */
> + if (substream->runtime->state == SNDRV_PCM_STATE_PAUSED)
> + substream->runtime->stop_operating = true;
[Severity: High]
Does setting substream->runtime->stop_operating = true here without issuing
SNDRV_PCM_TRIGGER_STOP leave drivers in a paused state when transitioning to
SNDRV_PCM_STATE_XRUN or SNDRV_PCM_STATE_SETUP?
Normally, when stopping a paused stream via snd_pcm_prepare() or
snd_pcm_drop(), ALSA unpauses the stream first before calling snd_pcm_stop():
sound/core/pcm_native.c:snd_pcm_prepare() {
scoped_guard(pcm_stream_lock_irq, substream) {
switch (substream->runtime->state) {
case SNDRV_PCM_STATE_PAUSED:
snd_pcm_pause(substream, false);
fallthrough;
case SNDRV_PCM_STATE_SUSPENDED:
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
break;
}
}
}
Because snd_pcm_pause(substream, false) sets runtime->state to
SNDRV_PCM_STATE_RUNNING, snd_pcm_do_stop() sees snd_pcm_running(substream) ==
true and invokes substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP).
However, when snd_pcm_stop() -> snd_pcm_do_stop() is called directly on a
stream in SNDRV_PCM_STATE_PAUSED (for example, when __snd_pcm_lib_xfer() ->
snd_pcm_update_state() -> __snd_pcm_xrun() triggers an XRUN after a partial
read/write while paused leaves avail >= runtime->stop_threshold, when
pcm_lib_apply_appl_ptr() -> ops->ack() returns -EPIPE, or if
snd_pcm_pause(substream, false) fails), snd_pcm_running(substream) is false.
With this change, snd_pcm_do_stop() sets runtime->stop_operating = true
without calling ops->trigger(SNDRV_PCM_TRIGGER_STOP), and snd_pcm_post_stop()
then overwrites runtime->state to SNDRV_PCM_STATE_XRUN (or
SNDRV_PCM_STATE_SETUP). A subsequent snd_pcm_prepare() or snd_pcm_drop() no
longer sees SNDRV_PCM_STATE_PAUSED, skips snd_pcm_pause() and snd_pcm_stop(),
and calls snd_pcm_sync_stop() -> ops->sync_stop() on a stream that only ever
received SNDRV_PCM_TRIGGER_PAUSE_PUSH and never received
SNDRV_PCM_TRIGGER_STOP:
1. In sound/virtio/virtio_pcm_ops.c, virtsnd_pcm_trigger() does not set
vss->stopped = true on SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
scoped_guard(spinlock_irqsave, &vss->lock) {
if (command != SNDRV_PCM_TRIGGER_PAUSE_PUSH)
vss->stopped = true;
vss->xfer_enabled = false;
}
At this commit, virtsnd_pcm_sync_stop() checks:
scoped_guard(spinlock_irqsave, &vss->lock) {
vss->xfer_enabled = false;
need_release = vss->stopped || vss->msg_count;
if (need_release)
vss->stopped = true;
}
cancel_work_sync(&vss->elapsed_period);
if (!need_release)
return 0;
If vss->msg_count is 0 when the paused stream enters XRUN, vss->stopped is
false and virtsnd_pcm_sync_stop() skips sending VIRTIO_SND_R_PCM_RELEASE.
Furthermore, once the follow-up commit ("ALSA: virtio: serialize capture
lifecycle and reset state") removes the paused-ACK stop_threshold check from
virtsnd_pcm_cp_ack(), a paused partial read/write that triggers XRUN in
snd_pcm_update_state() leaves both vss->stopped and vss->xfer_xrun false while
runtime->state is SNDRV_PCM_STATE_XRUN. A subsequent SNDRV_PCM_IOCTL_SYNC_PTR
ioctl (via snd_pcm_sync_ptr() -> pcm_lib_apply_appl_ptr()) can then invoke
virtsnd_pcm_pb_ack() or virtsnd_pcm_cp_ack(), bypass the vss->stopped and
vss->xfer_xrun guards, and queue new virtqueue DMA requests or advance staged
capture counters while in XRUN.
2. In sound/core/pcm_dmaengine.c, SNDRV_PCM_TRIGGER_PAUSE_PUSH calls
dmaengine_pause() while dmaengine_terminate_async() is only called on
SNDRV_PCM_TRIGGER_STOP. In snd_dmaengine_pcm_sync_stop():
status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
if (status != DMA_PAUSED)
dmaengine_synchronize(prtd->dma_chan);
Because the channel remains in DMA_PAUSED and was never terminated,
snd_dmaengine_pcm_sync_stop() skips synchronization and leaves the paused
DMA transfer active across prepare.
3. In sound/usb/pcm.c and sound/usb/endpoint.c, SNDRV_PCM_TRIGGER_PAUSE_PUSH
only clears the URB data callback whereas stop_endpoints() is only called on
SNDRV_PCM_TRIGGER_STOP. When snd_usb_pcm_sync_stop() calls wait_clear_urbs():
if (atomic_read(&ep->state) != EP_STATE_STOPPING)
return 0;
It returns immediately without stopping or draining the USB endpoints.
Should snd_pcm_do_stop() also ensure the stream is triggered to stop (or
Only treat SNDRV_PCM_STATE_PAUSED as running for the stop trigger when
substream->runtime->trigger_master == substream) rather than only setting
stop_operating = true?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028094132.20364-1-mynameisjune111@gmail.com?part=15
next prev parent reply other threads:[~2026-10-28 10:21 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 9:41 [PATCH v7 00/16] ALSA: virtio: staged capture and dsnoop recovery Joonho Lee
2026-10-28 9:41 ` [PATCH v7 01/16] ALSA: virtio: Propagate PCM send failures through ACK Joonho Lee
2026-10-28 10:07 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 02/16] ALSA: virtio: Recover PCM state after a failed start Joonho Lee
2026-10-28 10:18 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 03/16] ALSA: virtio: Retain queued messages through device reset Joonho Lee
2026-10-28 10:15 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 04/16] ALSA: virtio: Keep PCM DMA buffers alive through device ownership Joonho Lee
2026-10-28 10:12 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 05/16] ALSA: virtio: Keep control payloads alive through DMA completion Joonho Lee
2026-10-28 9:54 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 06/16] ALSA: virtio: wait through signals for PCM teardown Joonho Lee
2026-10-28 10:07 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 07/16] ALSA: virtio: stage VZ capture and restart paused streams Joonho Lee
2026-10-28 10:14 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 08/16] ALSA: virtio: account staged capture reads before RX refill Joonho Lee
2026-10-28 9:54 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 09/16] ALSA: virtio: prioritize staged capture period work Joonho Lee
2026-10-28 10:04 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 10/16] ALSA: pcm: mark stop-threshold accesses for capture policy sampling Joonho Lee
2026-10-28 9:47 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 11/16] ALSA: virtio-snd: fix dsnoop capture with staged buffers Joonho Lee
2026-10-28 10:20 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 12/16] ALSA: virtio: complete control transitions and preserve drain tail Joonho Lee
2026-10-28 9:57 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 13/16] ALSA: virtio: fence staged capture state and recovery Joonho Lee
2026-10-28 10:09 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 14/16] docs: describe virtio-sound capture options Joonho Lee
2026-10-28 9:51 ` sashiko-bot
2026-10-28 9:41 ` [PATCH v7 15/16] ALSA: pcm: synchronize stopped paused streams Joonho Lee
2026-10-28 10:21 ` sashiko-bot [this message]
2026-10-28 9:41 ` [PATCH v7 16/16] ALSA: virtio: serialize capture lifecycle and reset state Joonho Lee
2026-10-28 10:26 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-187743@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=eperezma@redhat.com \
--cc=linux-sound@vger.kernel.org \
--cc=mst@redhat.com \
--cc=mynameisjune111@gmail.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=virtualization@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.