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 v17 10/12] ALSA: virtio: serialize staged capture lifecycle and defer paused XRUNs
Date: Thu, 05 Nov 2026 07:41:43 +0000 [thread overview]
Message-ID: <sashiko-outbox-198691@kernel.org> (raw)
In-Reply-To: <20261105070845.6449-11-mynameisjune111@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] ALSA: virtio: missing xfer_xrun latch in virtsnd_pcm_transfer_failed()
--
commit 42ba5fb421db3215b1318325133b70f45151e844
Author: Joonho Lee <mynameisjune111@gmail.com>
ALSA: virtio: serialize staged capture lifecycle and defer paused XRUNs
This commit introduces request-owned RX staging for capture streams,
serializes PCM lifecycle operations with lifecycle_lock, and defers XRUN
handling for paused linked streams until resume.
> diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
> index 706d59d8c7201..36f8128a3f30c 100644
> --- a/sound/virtio/virtio_pcm_ops.c
> +++ b/sound/virtio/virtio_pcm_ops.c
[ ... ]
> @@ -637,132 +1739,515 @@ static void virtsnd_pcm_transfer_failed(struct virtio_pcm_substream *vss)
> vss->substream->runtime->stop_operating = true;
> }
>
> +/* Caller holds vss->lock; a paused ACK must not trigger linked XRUN. */
> +static int virtsnd_pcm_ack_xrun_locked(struct virtio_pcm_substream *vss,
> + struct snd_pcm_runtime *runtime)
> +{
> + vss->xfer_xrun = true;
> + if (runtime->state == SNDRV_PCM_STATE_PAUSED) {
> + vss->xfer_enabled = false;
> + runtime->stop_operating = true;
> + virtsnd_pcm_schedule_period_elapsed(vss);
> + return -EBADFD;
> + }
> + return -EPIPE;
> +}
> +
> +static int virtsnd_pcm_pb_ack_locked(struct snd_pcm_substream *substream)
> +{
> + struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
> + struct snd_pcm_runtime *runtime = substream->runtime;
> + struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss);
> + struct virtsnd_pcm_transfer transfer = {};
> + bool paused;
> + int rc;
> +
> + scoped_guard(spinlock_irqsave, &queue->lock) {
> + guard(spinlock)(&vss->lock);
> + paused = runtime->state == SNDRV_PCM_STATE_PAUSED;
> + if (vss->preparing)
> + return -EBADFD;
> + /* A latched XRUN must not re-arm sync_stop once teardown began. */
> + if (vss->stopped && vss->xfer_xrun)
> + return -EBADFD;
> + if (vss->xfer_xrun) {
> + rc = virtsnd_pcm_ack_xrun_locked(vss, runtime);
> + } else {
> + if (!vss->prepared || vss->stopped)
> + return -EBADFD;
> + transfer.indirect = vss->pcm_indirect;
> + rc = snd_pcm_indirect_playback_transfer(substream,
> + &transfer.indirect,
> + virtsnd_pcm_trans_copy);
> + }
> + if (!rc)
> + rc = transfer.error;
> + if (rc) {
> + if (paused)
> + rc = virtsnd_pcm_ack_xrun_locked(vss, runtime);
> + else
> + virtsnd_pcm_transfer_failed(vss);
> + } else {
> + vss->pcm_indirect = transfer.indirect;
> + }
> + }
[ ... ]
> +static int virtsnd_pcm_cp_ack_locked(struct snd_pcm_substream *substream)
> +{
> + struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
> + struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss);
> + struct snd_pcm_runtime *runtime = substream->runtime;
> + struct virtsnd_pcm_transfer transfer = {};
> + bool paused;
> + int rc;
> +
> + if (vss->capture_staging) {
> + rc = virtsnd_pcm_capture_staged_ack(vss, runtime);
> + if (rc == -EPIPE) {
> + guard(spinlock_irqsave)(&vss->lock);
> + virtsnd_pcm_transfer_failed(vss);
> + }
> + return rc;
> + }
> +
> + scoped_guard(spinlock_irqsave, &queue->lock) {
> + guard(spinlock)(&vss->lock);
> + paused = runtime->state == SNDRV_PCM_STATE_PAUSED;
> + if (vss->preparing)
> + return -EBADFD;
> + /* A latched XRUN must not re-arm sync_stop once teardown began. */
> + if (vss->stopped && vss->xfer_xrun)
> + return -EBADFD;
> + if (vss->xfer_xrun) {
> + rc = virtsnd_pcm_ack_xrun_locked(vss, runtime);
> + } else {
> + if (!vss->prepared ||
> + (vss->stopped &&
> + runtime->state != SNDRV_PCM_STATE_DRAINING))
> + return -EBADFD;
> + transfer.indirect = vss->pcm_indirect;
> + rc = snd_pcm_indirect_capture_transfer(substream,
> + &transfer.indirect,
> + virtsnd_pcm_trans_copy);
> + }
> + if (!rc)
> + rc = transfer.error;
> + if (rc) {
> + if (paused)
> + rc = virtsnd_pcm_ack_xrun_locked(vss, runtime);
> + else
> + virtsnd_pcm_transfer_failed(vss);
> + } else {
> + vss->pcm_indirect = transfer.indirect;
> + }
> + }
[Severity: Medium]
Should virtsnd_pcm_transfer_failed() in sound/virtio/virtio_pcm_ops.c also
latch vss->xfer_xrun = true?
When a non-paused indirect playback or capture ACK transfer fails in
virtsnd_pcm_pb_ack_locked() or virtsnd_pcm_cp_ack_locked() (for example,
when snd_pcm_indirect_playback_transfer() or
snd_pcm_indirect_capture_transfer() returns -EPIPE on a negative appl_ptr
diff, or virtsnd_pcm_msg_send() sets transfer.error), the error path calls
virtsnd_pcm_transfer_failed():
static void virtsnd_pcm_transfer_failed(struct virtio_pcm_substream *vss)
{
vss->xfer_enabled = false;
vss->stopped = true;
vss->substream->runtime->stop_operating = true;
}
Unlike the paused path (which calls virtsnd_pcm_ack_xrun_locked()) and the
staged capture path (where virtsnd_pcm_capture_staged_ack() calls
virtsnd_pcm_ack_xrun_locked() before virtsnd_pcm_transfer_failed()),
virtsnd_pcm_transfer_failed() leaves vss->xfer_xrun false while vss->prepared
and vss->stopped are true.
Because vss->xfer_xrun is not set:
1. In sound/virtio/virtio_pcm_msg.c, in-flight non-empty RX completions
arriving in virtsnd_pcm_msg_complete() for a non-staged capture stream bypass
the early retirement check:
if (vss->direction == SNDRV_PCM_STREAM_CAPTURE &&
(!vss->prepared || vss->xfer_xrun ||
(vss->stopped && written_bytes <= sizeof(*msg->status)))) {
and continue copying data and advancing vss->hw_ptr and
vss->capture_copied_total after the failed ACK rolled back vss->pcm_indirect
and appl_ptr.
2. If the capture stream is in SNDRV_PCM_STATE_DRAINING, the stopped-plus-XRUN
admission check (if (vss->stopped && vss->xfer_xrun) return -EBADFD) in
virtsnd_pcm_cp_ack_locked() is not armed.
3. Any call to virtsnd_pcm_pb_pointer() or virtsnd_pcm_cp_pointer() before
teardown (such as across the stream lock drop when locking a linked group in
__snd_pcm_xrun()) does not see vss->xfer_xrun set, so it invokes
snd_pcm_indirect_playback_pointer() or snd_pcm_indirect_capture_pointer()
instead of returning SNDRV_PCM_POS_XRUN.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261105070845.6449-1-mynameisjune111@gmail.com?part=10
next prev parent reply other threads:[~2026-11-05 7:41 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 7:08 [PATCH v17 00/12] ALSA: virtio: fix capture lifetime and accounting Joonho Lee
2026-11-05 7:08 ` [PATCH v17 01/12] ALSA: pcm: mark stop-threshold accesses for capture policy sampling Joonho Lee
2026-11-05 7:12 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 02/12] ALSA: pcm: report partial progress under the stream lock Joonho Lee
2026-11-05 7:14 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 03/12] ALSA: pcm: add an optional reset operation " Joonho Lee
2026-11-05 7:14 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 04/12] ALSA: virtio: Propagate PCM send failures through ACK Joonho Lee
2026-11-05 7:37 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 05/12] ALSA: virtio: Recover PCM state after a failed start Joonho Lee
2026-11-05 7:33 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 06/12] ALSA: virtio: Retain queued messages through device reset Joonho Lee
2026-11-05 7:39 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 07/12] ALSA: virtio: retain PCM DMA buffers and validate capture completions Joonho Lee
2026-11-05 7:43 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 08/12] ALSA: virtio: Keep control payloads alive through DMA completion Joonho Lee
2026-11-05 7:19 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 09/12] ALSA: virtio: wait through signals for PCM teardown Joonho Lee
2026-11-05 7:29 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 10/12] ALSA: virtio: serialize staged capture lifecycle and defer paused XRUNs Joonho Lee
2026-11-05 7:41 ` sashiko-bot [this message]
2026-11-05 7:08 ` [PATCH v17 11/12] ALSA: virtio: prioritize staged capture period work Joonho Lee
2026-11-05 7:24 ` sashiko-bot
2026-11-05 7:08 ` [PATCH v17 12/12] docs: describe virtio-sound capture options Joonho Lee
2026-11-05 7:20 ` 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-198691@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox