On 19/06/2020 05:54, Vinod Koul wrote:
On partial_drain completion we should be in SNDRV_PCM_STATE_RUNNING state, so set that for partially draining streams in snd_compr_drain_notify() and use a flag for partially draining streams
While at it, add locks for stream state change in snd_compr_drain_notify() as well.
Fixes: f44f2a5417b2 ("ALSA: compress: fix drain calls blocking other compress functions (v6)") Reported-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Signed-off-by: Vinod Koul vkoul@kernel.org
Reviewed-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Tested-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org
include/sound/compress_driver.h | 12 +++++++++++- sound/core/compress_offload.c | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index 3df8d8c90191..93a5897201ea 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h @@ -66,6 +66,7 @@ struct snd_compr_runtime {
- @direction: stream direction, playback/recording
- @metadata_set: metadata set flag, true when set
- @next_track: has userspace signal next track transition, true when set
*/
- @partial_drain: undergoing partial_drain for stream, true when set
- @private_data: pointer to DSP private data
- @dma_buffer: allocated buffer if any
@@ -78,6 +79,7 @@ struct snd_compr_stream { enum snd_compr_direction direction; bool metadata_set; bool next_track;
- bool partial_drain; void *private_data; struct snd_dma_buffer dma_buffer; };
@@ -187,7 +189,15 @@ static inline void snd_compr_drain_notify(struct snd_compr_stream *stream) if (snd_BUG_ON(!stream)) return;
- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
mutex_lock(&stream->device->lock);
/* for partial_drain case we are back to running state on success */
if (stream->partial_drain) {
stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
stream->partial_drain = false; /* clear this flag as well */
} else {
stream->runtime->state = SNDRV_PCM_STATE_SETUP;
}
mutex_unlock(&stream->device->lock);
wake_up(&stream->runtime->sleep); }
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index e618580feac4..1c4b2cf450a0 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -803,6 +803,9 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP); if (!retval) {
/* clear flags and stop any drain wait */
stream->partial_drain = false;
snd_compr_drain_notify(stream); stream->runtime->total_bytes_available = 0; stream->runtime->total_bytes_transferred = 0;stream->metadata_set = false;
@@ -960,6 +963,7 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream) if (stream->next_track == false) return -EPERM;
- stream->partial_drain = true; retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN); if (retval) { pr_debug("Partial drain returned failure\n");