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

Commit 541748cd authored by Bhalchandra Gajare's avatar Bhalchandra Gajare Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: msm-cpe-lsm: Fix crash during look-ahead buferring



In order to read the data after keyword detection event, a thread is
created to read the buffers in ping-pong manner. When command to stop
buffering is received, it is possible that thread is not completely
exited before the buffers are de-allocated. In such case, the thread
results into an crash due to null-pointer dereference. Fix the crash by
making sure the buferring thread has exited before de-allocating the
buffers.

Change-Id: Ic0d5a851c5cc374ce472c53282a319aeceda1243
Signed-off-by: default avatarBhalchandra Gajare <gajare@codeaurora.org>
parent 4fe162d7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ struct wcd_cpe_lsm_lab {
	struct wcd_cpe_lab_hw_params hw_params;
	struct wcd_cpe_data_pcm_buf *pcm_buf;
	wait_queue_head_t period_wait;
	struct completion thread_complete;
};

struct cpe_lsm_session {
+24 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#define LISTEN_MAX_PERIOD_SIZE     4096
#define LISTEN_MIN_PERIOD_SIZE     320

#define MSM_CPE_LAB_THREAD_TIMEOUT (3 * (HZ/10))

/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
@@ -331,6 +332,8 @@ static int msm_cpe_lab_thread(void *data)

	pr_debug("%s: Exiting LAB thread\n", __func__);

	complete(&lab->thread_complete);

	return 0;
}

@@ -600,6 +603,18 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
				pr_debug("%s: Thread stop rc%x\n",
					 __func__, rc);
			}

			/* Wait for the lab thread to exit */
			rc = wait_for_completion_timeout(
					&lab_sess->thread_complete,
					MSM_CPE_LAB_THREAD_TIMEOUT);
			if (!rc) {
				dev_err(rtd->dev,
					"%s: Wait for lab thread timedout\n",
					__func__);
				return -ETIMEDOUT;
			}

			rc = lsm_ops->lsm_lab_stop(cpe->core_handle, session);
			if (rc)
				pr_err("%s: Lab stop status %d\n",
@@ -633,8 +648,10 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
			if (rc) {
				pr_err("%s: Lab Enable Failed rc %d\n",
				       __func__, rc);
				lab_sess->lab_enable = false;
				return rc;
			}

			lab_sess->substream = substream;
			dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
			dma_buf->dev.dev = substream->pcm->card->dev;
@@ -643,8 +660,12 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
			dma_buf->addr =  lab_sess->pcm_buf[0].phys;
			dma_buf->bytes = (lab_sess->hw_params.buf_sz *
					lab_sess->hw_params.period_count);
			if (!dma_buf->area)
			if (!dma_buf->area) {
				lab_sess->lab_enable = false;
				return -ENOMEM;
			}

			init_completion(&lab_sess->thread_complete);
			snd_pcm_set_runtime_buffer(substream,
						   &substream->dma_buffer);
		} else {
@@ -955,6 +976,8 @@ static int msm_cpe_lsm_lab_start(struct snd_pcm_substream *substream,
	lsm_ops = &cpe->lsm_ops;
	lab_sess = &session->lab;

	INIT_COMPLETION(lab_sess->thread_complete);

	if (lab_sess->lab_enable &&
	    event_status->status ==
	    LSM_VOICE_WAKEUP_STATUS_DETECTED) {