Explorar el Código

msm: eva: fix DSP session deletion racing

The racing to delete DSP session may happen after DSP SSR when
EVA DSP driver just sent session deletion command to CPU driver.

Change-Id: I252000bc2c04148874db02b50d0a94c10edbb6e6
Signed-off-by: George Shen <[email protected]>
George Shen hace 2 años
padre
commit
e30e31d72b
Se han modificado 2 ficheros con 27 adiciones y 2 borrados
  1. 2 0
      msm/eva/msm_cvp_buf.c
  2. 25 2
      msm/eva/msm_cvp_dsp.c

+ 2 - 0
msm/eva/msm_cvp_buf.c

@@ -1833,6 +1833,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst,
 		goto err_no_mem;
 	}
 	buf->smem->pkt_type = buf->smem->buf_idx = 0;
+	atomic_inc(&buf->smem->refcount);
 
 	dprintk(CVP_MEM, "%s dma_buf %pK\n", __func__, buf->smem->dma_buf);
 
@@ -1875,6 +1876,7 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst,
 			"%s: %x : fd %x %s size %d",
 			__func__, hash32_ptr(inst->session), buf->fd,
 			smem->dma_buf->name, buf->size);
+		atomic_dec(&smem->refcount);
 		msm_cvp_smem_free(smem);
 		kmem_cache_free(cvp_driver->smem_cache, smem);
 	} else {

+ 25 - 2
msm/eva/msm_cvp_dsp.c

@@ -341,15 +341,33 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev)
 	struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL;
 	struct msm_cvp_inst *inst = NULL;
 	struct list_head *s = NULL, *next_s = NULL;
+	u32 max_num_retries = 100;
 
 	dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__);
 
+	mutex_lock(&me->rx_lock);
+	while (max_num_retries > 0) {
+		if (me->pending_dsp2cpu_cmd.type !=
+				CVP_INVALID_RPMSG_TYPE) {
+			mutex_unlock(&me->rx_lock);
+			usleep_range(1000, 5000);
+			mutex_lock(&me->rx_lock);
+		} else {
+			break;
+		}
+		max_num_retries--;
+	}
+
+	if (!max_num_retries)
+		dprintk(CVP_ERR, "stuck processing pending DSP cmds\n");
+
 	mutex_lock(&me->tx_lock);
 	cvp_hyp_assign_from_dsp();
 
 	me->chan = NULL;
 	me->state = DSP_UNINIT;
 	mutex_unlock(&me->tx_lock);
+	mutex_unlock(&me->rx_lock);
 
 	while ((frpc_node = dequeue_frpc_node())) {
 		s = &frpc_node->dsp_sessions.list;
@@ -1819,8 +1837,6 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd)
 	mutex_lock(&buf_list->lock);
 	list_for_each_safe(ptr, next, &buf_list->list) {
 		buf = list_entry(ptr, struct cvp_internal_buf, list);
-		dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n",
-					buf->fd, dsp2cpu_cmd->sbuf.fd);
 
 		if (!buf->smem) {
 			dprintk(CVP_DSP, "Empyt smem\n");
@@ -1831,6 +1847,8 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd)
 		if (buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) {
 			dprintk(CVP_DSP, "%s find device addr 0x%x\n",
 				__func__, buf->smem->device_addr);
+			dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n",
+				buf->fd, dsp2cpu_cmd->sbuf.fd);
 
 			rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf);
 			if (rc) {
@@ -1905,6 +1923,11 @@ wait_dsp:
 		dprintk(CVP_WARN, "%s received interrupt signal\n", __func__);
 	} else {
 		mutex_lock(&me->rx_lock);
+		if (me->state == DSP_UNINIT) {
+			/* DSP SSR may have happened */
+			mutex_unlock(&me->rx_lock);
+			goto wait_dsp;
+		}
 		switch (me->pending_dsp2cpu_cmd.type) {
 		case DSP2CPU_POWERON:
 		{