All of lore.kernel.org
 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 v6 13/14] ALSA: virtio: fence staged capture state and recovery
Date: Wed, 28 Oct 2026 03:27:30 +0000	[thread overview]
Message-ID: <sashiko-outbox-187421@kernel.org> (raw)
In-Reply-To: <20261028025317.92450-14-mynameisjune111@gmail.com>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] ALSA: virtio: deadlock and broken retry in virtsnd_pcm_pause_restart_pause()
- [High] ALSA: virtio: XRUN wakeup suppressed in virtsnd_pcm_pause_restart_fail()
- [High] ALSA: virtio: premature paused stop arming in virtsnd_pcm_cp_ack()
- [High] ALSA: virtio: post-reset substream state clobbered after virtsnd_reset_vqs()
- [High] ALSA: virtio: desynchronized prepared and stopped state on prepare and stop
- [High] ALSA: virtio: missing paused stop arming in non-staged virtsnd_pcm_cp_ack()
--

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

ALSA: virtio: fence staged capture state and recovery

This commit tracks device preparation under the substream lock, fences
virtqueue submissions and state transitions across pause, reset, and open
failure paths, and updates staged capture ACK and XRUN recovery handling.

> diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c
> index df7091b74a521..852cc27ac4a45 100644
> --- a/sound/virtio/virtio_card.c
> +++ b/sound/virtio/virtio_card.c
> @@ -348,6 +348,16 @@ static void virtsnd_reset_vqs(struct virtio_snd *snd)
>  	struct virtio_device *vdev = snd->vdev;
>  	unsigned int i;
>  
> +	for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) {
> +		struct virtio_pcm_substream *vss = &snd->substreams[i];
> +		struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss);
> +
> +		guard(spinlock_irqsave)(&queue->lock);
> +		guard(spinlock)(&vss->lock);
> +		vss->prepared = false;
> +		vss->xfer_enabled = false;
> +		vss->suspended = true;
> +	}
>  	virtio_reset_device(vdev);
>  
>  	/* Deleting a virtqueue does not unmap its outstanding descriptors. */
> @@ -364,9 +374,20 @@ static void virtsnd_reset_vqs(struct virtio_snd *snd)
>  		spin_unlock_irqrestore(&queue->lock, flags);
>  	}
>  
> -	vdev->config->del_vqs(vdev);
> -	for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i)
> +	for (i = 0; i < VIRTIO_SND_VQ_MAX; ++i) {
> +		guard(spinlock_irqsave)(&snd->queues[i].lock);
>  		snd->queues[i].vqueue = NULL;
> +	}
> +	vdev->config->del_vqs(vdev);
> +	for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) {
> +		struct virtio_pcm_substream *vss = &snd->substreams[i];
> +
> +		cancel_work_sync(&vss->elapsed_period);
> +		guard(spinlock_irqsave)(&vss->lock);
> +		vss->stopped = false;
> +		vss->xfer_xrun = false;
> +		vss->pause_restart_state = VIRTSND_PCM_PAUSE_RESTART_NONE;
> +	}
>  }

[Severity: High]
Can resetting vss->stopped, vss->xfer_xrun, and vss->pause_restart_state
inside virtsnd_reset_vqs() get clobbered by in-flight control message
senders that are only woken up afterwards?

In virtsnd_freeze() (and virtsnd_remove()), the teardown sequence runs:

  virtsnd_ctl_msg_cancel_all(snd);
  virtsnd_reset_vqs(snd);
  virtsnd_ctl_msg_cleanup(snd);

virtsnd_ctl_msg_cancel_all() marks pending control messages with
msg->cancelled = true, but it does not complete msg->notify. The threads
waiting in virtsnd_ctl_msg_send_sync() are only woken later when
virtsnd_ctl_msg_cleanup() calls virtsnd_ctl_msg_complete().

When a thread blocked in virtsnd_pcm_pause_restart_send() wakes up after
virtsnd_reset_vqs() has already reset the substream state,
virtsnd_ctl_msg_uncertain(msg, rc) returns true and vss->pause_restart_state
(now VIRTSND_PCM_PAUSE_RESTART_NONE) no longer matches submitted_state:

  scoped_guard(spinlock_irqsave, &vss->lock) {
          if ((rc && uncertain) || vss->pause_restart_state != submitted_state) {
                  vss->pause_restart_state =
                          VIRTSND_PCM_PAUSE_RESTART_RESET_REQUIRED;
                  if (!rc)
                          rc = -EIO;
          } ...
  }

The woken caller then runs virtsnd_pcm_pause_restart_fail() (or
virtsnd_pcm_start_failed() in non-pause-restart mode), overwriting
vss->pause_restart_state with VIRTSND_PCM_PAUSE_RESTART_RESET_REQUIRED and
setting vss->stopped = true and vss->xfer_xrun = true after the reset has
already completed, leaving the substream wedged after virtsnd_restore().

[ ... ]

> diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c
> index c7e85b151c5c4..0685a001cf95d 100644
> --- a/sound/virtio/virtio_pcm_ops.c
> +++ b/sound/virtio/virtio_pcm_ops.c

[ ... ]

> @@ -223,7 +227,8 @@ virtsnd_pcm_pause_restart_fail(struct virtio_pcm_substream *vss,
>  	bool notify_xrun;
>  
>  	scoped_guard(spinlock_irqsave, &vss->lock) {
> -		notify_xrun = !vss->xfer_xrun;
> +		notify_xrun = vss->runtime_active && vss->xfer_enabled &&
> +			      !vss->xfer_xrun;
>  		vss->xfer_enabled = false;
>  		vss->stopped = true;
>  		vss->xfer_xrun = true;

[Severity: High]
Does requiring vss->xfer_enabled in virtsnd_pcm_pause_restart_fail()
suppress XRUN notifications when SNDRV_PCM_TRIGGER_PAUSE_RELEASE or
SNDRV_PCM_TRIGGER_PAUSE_PUSH fails?

When a stream is paused, vss->xfer_enabled is false. During
SNDRV_PCM_TRIGGER_PAUSE_RELEASE in virtsnd_pcm_pause_restart_start(),
vss->xfer_enabled remains false until virtsnd_pcm_pause_prepare() and
virtsnd_pcm_capture_send() both succeed:

  if (resume) {
          rc = virtsnd_pcm_pause_prepare(vss);
          if (rc) {
                  virtsnd_pcm_pause_restart_failed(vss);
                  return rc;
          }
          ...
  }
  scoped_guard(spinlock_irqsave, &queue->lock) {
          guard(spinlock)(&vss->lock);
          ...
          rc = virtsnd_pcm_capture_send(vss);
          if (!rc)
                  vss->xfer_enabled = true;
  }
  if (rc) {
          virtsnd_pcm_pause_restart_failed(vss);
          return rc;
  }

If either step fails, virtsnd_pcm_pause_restart_fail() sees
vss->xfer_enabled == false and skips virtsnd_pcm_schedule_period_elapsed().
Because snd_pcm_action_single() runs snd_pcm_undo_pause() (where
vss->xfer_xrun is already true) and skips snd_pcm_post_pause(), the stream
stays in SNDRV_PCM_STATE_PAUSED with vss->xfer_xrun latched to true and
virtsnd_pcm_period_elapsed() is never scheduled to transition it to
SNDRV_PCM_STATE_XRUN and wake blocked readers.

Similarly, in virtsnd_pcm_pause_restart_pause(), vss->xfer_enabled is
cleared to false at function entry before VIRTIO_SND_R_PCM_STOP or
virtsnd_pcm_pause_release_flush() runs, so any failure in
virtsnd_pcm_pause_restart_pause() also sees vss->xfer_enabled == false and
never schedules virtsnd_pcm_period_elapsed().

[ ... ]

> @@ -599,8 +614,6 @@ static int virtsnd_pcm_prepare(struct snd_pcm_substream *substream)
>  			return -EBADFD;
>  		}
>  
> -		vss->buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
> -		vss->hw_ptr = 0;
>  	} else {
>  		struct snd_pcm_runtime *runtime = substream->runtime;
>  		unsigned int buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
> @@ -616,31 +629,30 @@ static int virtsnd_pcm_prepare(struct snd_pcm_substream *substream)
>  		}
>  	}
>  
> -	/* ALSA prepare resets its pointers even after a suspended stream. */
> -	if (vss->capture_staging)
> +	scoped_guard(spinlock_irqsave, &vss->lock) {
> +		vss->prepared = false;
> +		vss->buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
>  		vss->hw_ptr = 0;
> -
> -	if (!pause_restart)
> -		vss->xfer_xrun = false;
> -	vss->suspended = false;
> -	vss->msg_count = 0;
> -	virtsnd_pcm_msg_reset(vss);
> -	if (vss->capture_staging) {
> -		scoped_guard(spinlock_irqsave, &vss->lock) {
> +		if (!pause_restart)
> +			vss->xfer_xrun = false;
> +		vss->suspended = false;
> +		vss->msg_count = 0;
> +		virtsnd_pcm_msg_reset(vss);
> +		memset(&vss->pcm_indirect, 0, sizeof(vss->pcm_indirect));
> +		vss->pcm_indirect.sw_buffer_size = vss->buffer_bytes;
> +		vss->pcm_indirect.hw_buffer_size = vss->buffer_bytes;
> +		if (vss->capture_staging) {
>  			vss->capture_boundary = substream->runtime->boundary;
>  			rc = virtsnd_pcm_capture_refresh_mode_locked(vss,
> -								     &free_running);
> +							     &free_running);
> +			if (rc)
> +				return rc;
>  		}
> -		if (rc)
> -			return rc;
>  	}
>  
> -	memset(&vss->pcm_indirect, 0, sizeof(vss->pcm_indirect));
> -	vss->pcm_indirect.sw_buffer_size =
> -		vss->pcm_indirect.hw_buffer_size =
> -		snd_pcm_lib_buffer_bytes(substream);
> -
>  	rc = virtsnd_pcm_dev_prepare(vss);
> +	scoped_guard(spinlock_irqsave, &vss->lock)
> +		vss->prepared = !rc;
>  	if (pause_restart) {
>  		if (rc) {
>  			virtsnd_pcm_pause_restart_fail(vss, false);
> @@ -759,13 +771,23 @@ static int virtsnd_pcm_pause_restart_pause(struct virtio_pcm_substream *vss)
>  
>  	scoped_guard(spinlock_irqsave, &vss->lock) {
>  		state = vss->pause_restart_state;
> -		if (state == VIRTSND_PCM_PAUSE_RESTART_RELEASE_SENT ||
> -		    state == VIRTSND_PCM_PAUSE_RESTART_RELEASED)
> -			return 0;
> +		if (state == VIRTSND_PCM_PAUSE_RESTART_RELEASED)
> +			return vss->xfer_xrun ? -EPIPE : 0;
>  		vss->xfer_enabled = false;
>  		vss->stopped = true;
>  	}
>  
> +	if (state == VIRTSND_PCM_PAUSE_RESTART_RELEASE_SENT) {
> +		rc = virtsnd_pcm_pause_restart_sync_stop(vss->substream);
> +		if (!rc) {
> +			guard(spinlock_irqsave)(&vss->lock);
> +			vss->stopped = true;
> +			if (vss->xfer_xrun)
> +				rc = -EPIPE;
> +		}
> +		return rc;
> +	}

[Severity: High]
Won't calling virtsnd_pcm_pause_restart_sync_stop() from inside
virtsnd_pcm_pause_restart_pause() deadlock on the PCM stream lock when
vss->elapsed_period work is pending or running?

Because vpcm->pcm->nonatomic is true, the ALSA PCM stream lock is a mutex
(substream->self_group.mutex), and ALSA holds it across substream->ops->trigger():

  CPU 0                                  CPU 1 (workqueue)
  snd_pcm_pause_lock_irq()
    pcm_stream_lock_irq()
    snd_pcm_action_single()
      snd_pcm_do_pause()
        virtsnd_pcm_trigger(PAUSE_PUSH)
          virtsnd_pcm_pause_restart_pause()
            virtsnd_pcm_pause_restart_sync_stop()
              cancel_work_sync(&vss->elapsed_period)
                                         virtsnd_pcm_period_elapsed()
                                           guard(pcm_stream_lock_irqsave)(substream)

virtsnd_pcm_period_elapsed() blocks waiting for pcm_stream_lock while
virtsnd_pcm_pause_restart_sync_stop() waits for virtsnd_pcm_period_elapsed()
to finish.

In addition, VIRTSND_PCM_PAUSE_RESTART_RELEASE_SENT is reached when an
earlier virtsnd_pcm_pause_release_flush() timed out, which called
virtsnd_pcm_pause_restart_failed() and set vss->xfer_xrun = true while
ALSA left runtime->state in SNDRV_PCM_STATE_RUNNING. When a subsequent
SNDRV_PCM_TRIGGER_PAUSE_PUSH retry drains the queue and returns -EPIPE
because vss->xfer_xrun is true, snd_pcm_action_single() runs
snd_pcm_undo_pause() and skips snd_pcm_post_pause(), keeping runtime->state
in SNDRV_PCM_STATE_RUNNING where snd_pcm_prepare() is rejected with -EBUSY.

>  	if (state == VIRTSND_PCM_PAUSE_RESTART_RESET_REQUIRED ||
>  	    virtsnd_pcm_pause_restart_transitioning(state)) {
>  		virtsnd_pcm_pause_restart_fail(vss, true);
> @@ -813,10 +835,9 @@ static int virtsnd_pcm_pause_restart_stop(struct virtio_pcm_substream *vss,
>  	enum virtio_pcm_pause_restart_state state;
>  	int rc;
>  
> -	if (suspend)
> -		vss->suspended = true;
> -
>  	scoped_guard(spinlock_irqsave, &vss->lock) {
> +		if (suspend)
> +			vss->suspended = true;
>  		vss->xfer_enabled = false;
>  		vss->stopped = true;
>  		state = vss->pause_restart_state;
> @@ -887,7 +908,7 @@ static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
>  
>  		scoped_guard(spinlock_irqsave, &queue->lock) {
>  			guard(spinlock)(&vss->lock);
> -			if (vss->stopped) {
> +			if (vss->stopped || !vss->prepared) {
>  				substream->runtime->stop_operating = true;
>  				return -EBADFD;
>  			}
> @@ -920,17 +941,18 @@ static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
>  		msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_START,
>  						GFP_KERNEL);
>  		if (!msg) {
> -			virtsnd_pcm_start_failed(vss, false);
> +			virtsnd_pcm_start_failed(vss);
>  			return -ENOMEM;
>  		}
>  
>  		rc = virtsnd_ctl_msg_send_sync(snd, msg);
>  		if (rc)
> -			virtsnd_pcm_start_failed(vss, false);
> +			virtsnd_pcm_start_failed(vss);
>  
>  		return rc;
>  	case SNDRV_PCM_TRIGGER_SUSPEND:
> -		vss->suspended = true;
> +		scoped_guard(spinlock_irqsave, &vss->lock)
> +			vss->suspended = true;
>  		fallthrough;

[Severity: High]
Are vss->prepared, vss->stopped, and vss->suspended kept consistent across
early prepare failures, sync_stop releases, and unprepared stop triggers?

1. In virtsnd_pcm_prepare(), vss->prepared = false is only set after the
early return checks for virtsnd_pcm_msg_pending_num(vss) and
virtsnd_pcm_dev_set_params(). If a stream is already in
SNDRV_PCM_STATE_PREPARED (with vss->prepared == true) and a re-prepare fails
in virtsnd_pcm_dev_set_params() or virtsnd_pcm_msg_pending_num(),
snd_pcm_do_prepare() leaves runtime->state as SNDRV_PCM_STATE_PREPARED and
virtsnd_pcm_prepare() returns with vss->prepared still true, allowing
subsequent START or ACK calls to queue transfers after a failed PREPARE.

2. In virtsnd_pcm_sync_stop() and virtsnd_pcm_pause_restart_sync_stop(),
sending VIRTIO_SND_R_PCM_RELEASE clears vss->stopped = false without
setting vss->prepared = false. After SNDRV_PCM_IOCTL_DROP releases the
stream on the device and moves runtime->state to SNDRV_PCM_STATE_SETUP,
vss->prepared remains true and vss->stopped is false, so a subsequent
SNDRV_PCM_IOCTL_SYNC_PTR (snd_pcm_sync_ptr() -> pcm_lib_apply_appl_ptr() ->
substream->ops->ack()) passes the !vss->prepared and vss->stopped checks in
virtsnd_pcm_pb_ack() and virtsnd_pcm_cp_ack() and queues descriptors on a
released stream.

3. Conversely, when !vss->prepared (such as after virtsnd_reset_vqs() sets
vss->prepared = false and vss->stopped = false), if SNDRV_PCM_TRIGGER_START
returns -EBADFD, snd_pcm_action_single() calls snd_pcm_undo_start() ->
virtsnd_pcm_trigger(SNDRV_PCM_TRIGGER_STOP). Because the
SNDRV_PCM_TRIGGER_STOP case does not check vss->prepared, it sets
vss->stopped = true and sends VIRTIO_SND_R_PCM_STOP to an unprepared
stream, and the next virtsnd_pcm_sync_stop() sends VIRTIO_SND_R_PCM_RELEASE
to the unconfigured stream, which fails and leaves vss->stopped latched to
true.

4. Also, vss->suspended = false in virtsnd_pcm_open() and the
if (!vss->suspended) check in virtsnd_pcm_prepare() still access
vss->suspended without holding vss->lock.

[ ... ]

> @@ -1352,7 +1376,9 @@ static int virtsnd_pcm_cp_ack(struct snd_pcm_substream *substream)
>  
>  	if (vss->capture_staging) {
>  		rc = virtsnd_pcm_capture_staged_ack(vss, runtime);
> -		if (rc == -EPIPE) {
> +		if (rc == -EPIPE ||
> +		    (!rc && runtime->state == SNDRV_PCM_STATE_PAUSED &&
> +		     snd_pcm_capture_avail(runtime) >= runtime->stop_threshold)) {
>  			guard(spinlock_irqsave)(&vss->lock);
>  			virtsnd_pcm_capture_arm_paused_stop(vss);
>  		}

[Severity: High]
Can arming virtsnd_pcm_capture_arm_paused_stop() inside virtsnd_pcm_cp_ack()
when rc == 0 leave vss->stopped = true while the ALSA substream remains in
SNDRV_PCM_STATE_PAUSED?

In __snd_pcm_lib_xfer(), a single read that wraps around the ring buffer
boundary is split across two loop iterations. pcm_lib_apply_appl_ptr() ->
substream->ops->ack() is called after each contiguous chunk, whereas
snd_pcm_update_state() is only called once after the entire transfer loop
finishes.

If snd_pcm_capture_avail(runtime) >= runtime->stop_threshold after the first
chunk at the wrap boundary, but avail drops below runtime->stop_threshold
after the second chunk completes the read, virtsnd_pcm_cp_ack() calls
virtsnd_pcm_capture_arm_paused_stop(vss) on the first chunk (setting
vss->stopped = true and vss->xfer_enabled = false), while
snd_pcm_update_state() sees avail < runtime->stop_threshold and keeps
runtime->state in SNDRV_PCM_STATE_PAUSED. Calling snd_pcm_forward(),
snd_pcm_rewind(), or snd_pcm_sync_ptr() while paused also invokes
pcm_lib_apply_appl_ptr() -> substream->ops->ack() without calling
snd_pcm_update_state().

When userspace subsequently unpauses the stream with
SNDRV_PCM_TRIGGER_PAUSE_RELEASE in native pause mode, virtsnd_pcm_trigger()
sees vss->stopped == true and fails with -EBADFD.

>  		return rc;
>  	}
>  
>  	scoped_guard(spinlock_irqsave, &queue->lock) {
>  		guard(spinlock)(&vss->lock);
> +		if (!vss->prepared)
> +			return -EBADFD;
>  		transfer.indirect = vss->pcm_indirect;
>  		if (vss->stopped && runtime->state != SNDRV_PCM_STATE_DRAINING) {
>  			rc = -EPIPE;

[Severity: High]
What happens in the non-staged capture path (!vss->capture_staging) when a
paused read crosses runtime->stop_threshold and snd_pcm_update_state()
moves the substream to SNDRV_PCM_STATE_XRUN?

Because virtsnd_pcm_capture_arm_paused_stop() is only called in the
vss->capture_staging branch of virtsnd_pcm_cp_ack(), a paused non-staged
capture stream that enters SNDRV_PCM_STATE_XRUN from snd_pcm_update_state()
after a partial read (or when virtsnd_pcm_cp_ack() returns -EPIPE) never
sets vss->stopped = true or runtime->stop_operating = true, since
snd_pcm_do_stop() is a no-op when !snd_pcm_running(substream).

As a result, the queued RX descriptors remain pending in the virtqueue and
subsequent snd_pcm_prepare() calls skip virtsnd_pcm_sync_stop() and fail
with -EBADFD at virtsnd_pcm_msg_pending_num(vss). Furthermore, on
!CONFIG_MMU, because virtsnd_pcm_msg_complete() now checks
vss->prepared && !vss->stopped instead of vss->xfer_enabled:

  #ifndef CONFIG_MMU
  	if (vss->direction == SNDRV_PCM_STREAM_CAPTURE &&
  	    vss->prepared && !vss->stopped &&
  	    written_bytes > sizeof(msg->status)) {
  ...
  		memcpy(runtime->dma_area + msg->data_offset,
  		       vss->owned_dma_area + msg->data_offset, data_bytes);
  	}
  #endif

if userspace calls snd_pcm_drop() followed by snd_pcm_hw_params(),
snd_pcm_lib_malloc_pages() can free and reallocate runtime->dma_area before
virtsnd_pcm_hw_params() clears vss->prepared, allowing a concurrent RX
completion in virtsnd_pcm_msg_complete() to copy into freed
runtime->dma_area.

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

  reply	other threads:[~2026-10-28  3:27 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28  2:53 [PATCH v6 00/14] ALSA: virtio: staged capture and dsnoop recovery Joonho Lee
2026-10-28  2:53 ` [PATCH v6 01/14] ALSA: virtio: Propagate PCM send failures through ACK Joonho Lee
2026-10-28  3:09   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 02/14] ALSA: virtio: Recover PCM state after a failed start Joonho Lee
2026-10-28  3:21   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 03/14] ALSA: virtio: Retain queued messages through device reset Joonho Lee
2026-10-28  3:19   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 04/14] ALSA: virtio: Keep PCM DMA buffers alive through device ownership Joonho Lee
2026-10-28  3:15   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 05/14] ALSA: virtio: Keep control payloads alive through DMA completion Joonho Lee
2026-10-28  3:07   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 06/14] ALSA: virtio: wait through signals for PCM teardown Joonho Lee
2026-10-28  3:12   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 07/14] ALSA: virtio: stage VZ capture and restart paused streams Joonho Lee
2026-10-28  3:27   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 08/14] ALSA: virtio: account staged capture reads before RX refill Joonho Lee
2026-10-28  3:03   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 09/14] ALSA: virtio: prioritize staged capture period work Joonho Lee
2026-10-28  3:00   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 10/14] ALSA: pcm: mark stop-threshold accesses for capture policy sampling Joonho Lee
2026-10-28  2:58   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 11/14] ALSA: virtio-snd: fix dsnoop capture with staged buffers Joonho Lee
2026-10-28  3:16   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 12/14] ALSA: virtio: complete control transitions and preserve drain tail Joonho Lee
2026-10-28  3:06   ` sashiko-bot
2026-10-28  2:53 ` [PATCH v6 13/14] ALSA: virtio: fence staged capture state and recovery Joonho Lee
2026-10-28  3:27   ` sashiko-bot [this message]
2026-10-28  2:53 ` [PATCH v6 14/14] docs: describe virtio-sound capture options Joonho Lee
2026-10-28  2:58   ` 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-187421@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.