On Sun, 11 Oct 2026 14:54:26 +0200,
Ting-Han Hou wrote:
>
> Since commit fe981e67568c ("ALSA: virtio: use ack callback"), an I/O
> message is only queued to the device once the application has filled
> the whole period: virtsnd_pcm_msg_send() accumulates the transferred
> bytes in msg->length and queues the message when it reaches
> period_bytes. msg->length is reset to 0 only when the device completes
> the message.
>
> If the substream is stopped (e.g. snd_pcm_drop()) while a period is
> only partially filled, the corresponding message is never queued and
> keeps its partial length. virtsnd_pcm_prepare() resets msg_count,
> hw_ptr and the indirect PCM state, but not msg->length. After the
> next start, the stale length is added to the new data, the sum never
> equals period_bytes, and the message is never sent again. Playback
> then stalls once hw_ptr reaches that period: writes fail with -EIO
> ("DMA or IRQ trouble") and drain fails with -EIO. Capture is affected the
> same way after a partial read.
>
> Clear the fill level of all messages in prepare. Outside of the resume
> path, virtsnd_pcm_prepare() already refuses to run while I/O messages
> are pending, so no message is owned by the device at this point and the
> reset does not race with message completion.
>
> Reproduced in QEMU (virtio-sound-pci, wav audiodev): prepare, write 1.5
> periods, drop, prepare, write 16 full periods, drain. Without this
> patch WRITEI returns -EIO after 14 periods and DRAIN fails; with it all
> 16 periods are played and DRAIN succeeds. Period-aligned prefill works
> in both cases. The same sequence on capture (read 1.5 periods, drop,
> prepare, read 16 periods) fails with -EIO after 10 periods without this
> patch and reads all 16 with it.
>
> Found by code inspection, confirmed with the reproducer above.
>
> Fixes: fe981e67568c ("ALSA: virtio: use ack callback")
> Assisted-by: LLM
> Signed-off-by: Ting-Han Hou <[email protected]>
> ---
Applied to for-next branch now. Thanks.
Takashi