Linux virtualization list
 help / color / mirror / Atom feed
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 v21 04/12] ALSA: virtio: Propagate PCM send failures through ACK
Date: Mon, 09 Nov 2026 00:28:39 +0000	[thread overview]
Message-ID: <sashiko-outbox-204211@kernel.org> (raw)
In-Reply-To: <20261108235457.12688-5-mynameisjune111@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] ALSA: virtio: premature ACK admission in virtsnd_pcm_reset()
  during prepare
- [Low] ALSA: virtio: misplaced Fixes trailer and inaccurate commit
  message
--

commit d7d32fabac0905c34c390dcb86edfd7a2dc6b2c7
Author: Joonho Lee <mynameisjune111@gmail.com>

> ALSA: virtio: Propagate PCM send failures through ACK
> 
> virtsnd_pcm_msg_send() can fail while queueing a transfer. Restore the
> failed message's length and notify the device about earlier messages
> queued by the same call, so they do not remain stranded.
> 
> Propagate errors through the indirect transfer callback and commit its
> private cursor only after successful submission. Genuine transfer errors
> arm stop_operating and return -EPIPE so ALSA can retire the stream.
> 
> Close ACK admission under the PCM stream lock before sleeping teardown.
> Keep the prepared state protected by the substream lock and reject ACK
> through prepare and parameter changes. Reopen admission in the reset
> callback while the core holds the PCM lock for its pointer rebase. An
> ACK racing with teardown returns -EBADFD and preserves stop state.
> 
> Keep the polling feature path unchanged.
> 
> Fixes: fe981e67568c ("ALSA: virtio: use ack callback")
> 
> Reject a stopped playback ACK before the XRUN path can rearm
> stop_operating. For capture, allow the ordinary stopped tail only during
> DRAINING and only while no transfer XRUN is latched.
> 
> Latch a transfer failure before stopping PCM work. Once core reports the member XRUN, ACK returns -EBADFD to avoid another linked XRUN. ACK during prepare remains rejected until the core state reaches PREPARED.
> Signed-off-by: Joonho Lee <mynameisjune111@gmail.com>

[Severity: Low]
This isn't a runtime bug, but the Fixes: trailer sits in the middle of the
commit message rather than in the trailer block above Signed-off-by:, and
the final paragraph states that ACK returns -EBADFD once the core reports
XRUN whereas virtsnd_pcm_ack_state() returns -EPIPE for
SNDRV_PCM_STATE_XRUN in this patch.

> diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
> index 1091100a4c982..983c6f83d1231 100644
> --- a/sound/virtio/virtio_pcm_ops.c
> +++ b/sound/virtio/virtio_pcm_ops.c

[ ... ]

> @@ -461,41 +530,168 @@ virtsnd_pcm_cp_pointer(struct snd_pcm_substream *substream)
>  
> +/* The caller holds the PCM lock, also used by DROP and state transitions. */
> +static int virtsnd_pcm_ack_state(struct snd_pcm_substream *substream)
> +{
> +	switch (substream->runtime->state) {
> +	case SNDRV_PCM_STATE_XRUN:
> +		return -EPIPE;
> +	case SNDRV_PCM_STATE_PREPARED:
> +	case SNDRV_PCM_STATE_RUNNING:
> +	case SNDRV_PCM_STATE_PAUSED:
> +	case SNDRV_PCM_STATE_DRAINING:
> +		if (atomic_read(&substream->runtime->buffer_accessing) < 0)
> +			return -EBADFD;
> +		return 0;
> +	default:
> +		return -EBADFD;
> +	}
> +}

[ ... ]

> +static int virtsnd_pcm_cp_ack(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 virtsnd_pcm_transfer transfer = {};
> +	int rc;
> +
> +	rc = virtsnd_pcm_ack_state(substream);
> +	if (rc)
> +		return rc;
> +
> +	scoped_guard(spinlock_irqsave, &queue->lock) {
> +		guard(spinlock)(&vss->lock);
> +		if (vss->preparing || !vss->prepared)
> +			return -EBADFD;
> +		/* Keep only the post-STOP capture tail available during drain. */
> +		if (vss->stopped &&
> +		    (vss->xfer_xrun ||
> +		     substream->runtime->state != SNDRV_PCM_STATE_DRAINING))
> +			return -EBADFD;
> +		if (vss->xfer_xrun) {
> +			rc = -EPIPE;
> +		} else {
> +			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)
> +			virtsnd_pcm_transfer_failed(vss);
> +		else
> +			vss->pcm_indirect = transfer.indirect;
> +	}
> +	if (rc) {
> +		dev_err(&vss->snd->vdev->dev,
> +			"SID %u: capture ACK transfer failed: %d\n",
> +			vss->sid, rc);
> +		return -EPIPE;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * virtsnd_pcm_reset() - Reset PCM pointers and complete prepare admission.
> + * @substream: Kernel ALSA substream.
> + *
> + * Context: PCM stream lock held.
> + * Return: 0 on success, -errno on failure.
> + */
> +static int virtsnd_pcm_reset(struct snd_pcm_substream *substream)
> +{
> +	struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
> +	int rc;
> +
> +	rc = snd_pcm_lib_reset(substream);
> +	scoped_guard(spinlock_irqsave, &vss->lock) {
> +		if (vss->preparing) {
> +			vss->prepared = !rc;
> +			vss->preparing = false;
> +		}
> +	}
>  
> -	return snd_pcm_indirect_capture_transfer(substream, &vss->pcm_indirect,
> -						 virtsnd_pcm_trans_copy);
> +	return rc;
>  }

[Severity: Medium]
Can virtsnd_pcm_reset() reopen ACK admission on a substream before
snd_pcm_post_prepare() transitions the group to SNDRV_PCM_STATE_PREPARED?

CPU0                                  CPU1
snd_pcm_prepare(s0)
  snd_pcm_action_nonatomic(...)
    snd_pcm_do_prepare(s1)
      virtsnd_pcm_sync_stop(s1)
        vss1->stopped = false
      virtsnd_pcm_prepare(s1)
      snd_pcm_reset_substream(s1, ...)
        virtsnd_pcm_reset(s1)
          vss1->prepared = true
          vss1->preparing = false
    snd_pcm_do_prepare(s2)
      ... (sleeps or fails)
                                      snd_pcm_sync_ptr(s1)
                                        pcm_lib_apply_appl_ptr(s1, ...)
                                          virtsnd_pcm_pb_ack(s1) /
                                          virtsnd_pcm_cp_ack(s1)
                                            <-- accepted before post_prepare

In snd_pcm_action_group(), snd_pcm_do_prepare() runs sequentially on each
linked member before snd_pcm_post_prepare() runs on any of them, and
snd_pcm_action_nonatomic() only sets runtime->buffer_accessing to -1 on
the ioctl target substream (and snd_pcm_sync_ptr() does not check
buffer_accessing at all).  If a linked member s1 entered prepare from
PREPARED, PAUSED, or capture DRAINING, virtsnd_pcm_reset(s1) sets
vss1->prepared = true and vss1->preparing = false and releases s1's PCM
stream lock before s2 completes snd_pcm_do_prepare(s2).

While s2 sleeps in snd_pcm_do_prepare(s2) (or permanently if s2 fails
prepare, since snd_pcm_action_prepare has no undo_action), playback ACKs
on s1 queue new TX buffers to the virtqueue before prepare completes.  In
addition, because virtsnd_pcm_cp_ack() only checks runtime->state !=
SNDRV_PCM_STATE_DRAINING when vss->stopped is true, a capture substream
re-prepared from DRAINING has vss1->stopped == false after
virtsnd_pcm_sync_stop(s1) and accepts capture ACKs while runtime->state is
still DRAINING, driving vss1->pcm_indirect.sw_ready negative.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261108235457.12688-1-mynameisjune111@gmail.com?part=4

  reply	other threads:[~2026-11-09  0:28 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-08 23:54 [PATCH v21 00/12] ALSA: virtio: fix capture accounting Joonho Lee
2026-11-08 23:54 ` [PATCH v21 01/12] ALSA: pcm: mark stop-threshold accesses for capture policy sampling Joonho Lee
2026-11-09  0:01   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 02/12] ALSA: pcm: report partial progress under the stream lock Joonho Lee
2026-11-09  0:02   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 03/12] ALSA: pcm: add an optional reset operation " Joonho Lee
2026-11-09  0:05   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 04/12] ALSA: virtio: Propagate PCM send failures through ACK Joonho Lee
2026-11-09  0:28   ` sashiko-bot [this message]
2026-11-08 23:54 ` [PATCH v21 05/12] ALSA: virtio: Recover PCM state after a failed start Joonho Lee
2026-11-09  0:24   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 06/12] ALSA: virtio: Retain queued messages through device reset Joonho Lee
2026-11-09  0:16   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 07/12] ALSA: virtio: validate indirect capture appl_ptr accounting Joonho Lee
2026-11-09  0:26   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 08/12] ALSA: virtio: Keep control payloads alive through DMA completion Joonho Lee
2026-11-09  0:04   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 09/12] ALSA: virtio: wait through signals for PCM teardown Joonho Lee
2026-11-09  0:17   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 10/12] ALSA: virtio: gate starts during PCM prepare Joonho Lee
2026-11-09  0:34   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 11/12] ALSA: virtio: prioritize staged capture period work Joonho Lee
2026-11-09  0:07   ` sashiko-bot
2026-11-08 23:54 ` [PATCH v21 12/12] docs: describe virtio-sound capture options Joonho Lee
2026-11-09  0:11   ` sashiko-bot
2026-11-09  5:16 ` [PATCH v22 00/13] ALSA: virtio: validate PCM ACK and prepare completion Joonho Lee
2026-11-09  5:16   ` [PATCH v22 01/13] ALSA: pcm: mark stop-threshold accesses for capture policy sampling Joonho Lee
2026-11-09  5:21     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 02/13] ALSA: pcm: report partial progress under the stream lock Joonho Lee
2026-11-09  5:21     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 03/13] ALSA: pcm: add an optional reset operation " Joonho Lee
2026-11-09  5:25     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 04/13] ALSA: pcm: notify drivers after linked prepare completes Joonho Lee
2026-11-09  5:30     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 05/13] ALSA: virtio: propagate PCM send failures through ACK Joonho Lee
2026-11-09  5:42     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 06/13] ALSA: virtio: Recover PCM state after a failed start Joonho Lee
2026-11-09  5:42     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 07/13] ALSA: virtio: Retain queued messages through device reset Joonho Lee
2026-11-09  5:48     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 08/13] ALSA: virtio: validate indirect PCM ACK accounting Joonho Lee
2026-11-09  5:51     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 09/13] ALSA: virtio: Keep control payloads alive through DMA completion Joonho Lee
2026-11-09  5:25     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 10/13] ALSA: virtio: wait through signals for PCM teardown Joonho Lee
2026-11-09  5:30     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 11/13] ALSA: virtio: gate starts during PCM prepare Joonho Lee
2026-11-09  5:54     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 12/13] ALSA: virtio: prioritize staged capture period work Joonho Lee
2026-11-09  5:28     ` sashiko-bot
2026-11-09  5:16   ` [PATCH v22 13/13] docs: describe virtio-sound capture options Joonho Lee
2026-11-09  5:29     ` 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-204211@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