A paused stream can still own DMA requests even though snd_pcm_running() returns false. Stopping that stream without marking stop_operating lets a subsequent prepare skip sync_stop and encounter outstanding requests.
Mark a paused stream for synchronous stop when snd_pcm_do_stop() handles its actual stop transition. This also covers paused XRUN cleanup without having the driver predict a stop from an intermediate ACK position. The non-staged virtio-snd partial-read test previously failed its first prepare with -EBADFD. With the companion driver changes it prepares and captures 48000 frames. Playback pause/drop/prepare/write and reopen tests also pass under ARM64 QEMU with KASAN and lockdep. This changes the core stop path for paused PCM streams beyond virtio-snd. Coverage does not extend to all PCM drivers. Assisted-by: LLM Signed-off-by: Joonho Lee <[email protected]> --- diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index a2ea44c..ac2e5c2 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; return 0; /* unconditionally stop all substreams */ }
