Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd495394 authored by Banajit Goswami's avatar Banajit Goswami
Browse files

ASoC: compress: revert some code to avoid race condition



Revert some changes for compress offload path to avoid race
condition in drain and paartial-drain cases.

Change-Id: I9fbaaa0cb9c7e600e2a2998425d471534306dfb5
Signed-off-by: default avatarBanajit Goswami <bgoswami@codeaurora.org>
parent 7bb01ad6
Loading
Loading
Loading
Loading
+6 −45
Original line number Diff line number Diff line
@@ -711,7 +711,8 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
		return -EPERM;
	retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
	if (!retval) {
		snd_compr_drain_notify(stream);
		stream->runtime->state = SNDRV_PCM_STATE_SETUP;
		wake_up(&stream->runtime->sleep);
		stream->runtime->total_bytes_available = 0;
		stream->runtime->total_bytes_transferred = 0;
	}
@@ -757,41 +758,6 @@ int snd_compr_stop_error(struct snd_compr_stream *stream,
}
EXPORT_SYMBOL_GPL(snd_compr_stop_error);

static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
{
	int ret;

	/*
	 * We are called with lock held. So drop the lock while we wait for
	 * drain complete notification from the driver
	 *
	 * It is expected that driver will notify the drain completion and then
	 * stream will be moved to SETUP state, even if draining resulted in an
	 * error. We can trigger next track after this.
	 */
	stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
	mutex_unlock(&stream->device->lock);

	/* we wait for drain to complete here, drain can return when
	 * interruption occurred, wait returned error or success.
	 * For the first two cases we don't do anything different here and
	 * return after waking up
	 */

	ret = wait_event_interruptible(stream->runtime->sleep,
			(stream->runtime->state != SNDRV_PCM_STATE_DRAINING));
	if (ret == -ERESTARTSYS)
		pr_debug("wait aborted by a signal\n");
	else if (ret)
		pr_debug("wait for drain failed with %d\n", ret);


	wake_up(&stream->runtime->sleep);
	mutex_lock(&stream->device->lock);

	return ret;
}

static int snd_compr_drain(struct snd_compr_stream *stream)
{
	int retval;
@@ -801,13 +767,13 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
		return -EPERM;

	retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
	if (retval) {
		pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
	if (!retval) {
		stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
		wake_up(&stream->runtime->sleep);
		return retval;
	}

	return snd_compress_wait_for_drain(stream);
	return retval;
}

static int snd_compr_next_track(struct snd_compr_stream *stream)
@@ -843,14 +809,9 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
		return -EPERM;

	retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
	if (retval) {
		pr_debug("Partial drain returned failure\n");
		wake_up(&stream->runtime->sleep);
		return retval;
	}

	stream->next_track = false;
	return snd_compress_wait_for_drain(stream);
	return retval;
}

static int snd_compress_simple_ioctls(struct file *file,