Răsfoiți Sursa

msm: eva: Enhance DSP debugging

Validate session pointer passed in by DSP driver and save the
most recently un-mapped DSP buffers for SMMU fault debugging.

Change-Id: I1beebcce190874e3129fc1bd3806ffee61eb6d4d
Signed-off-by: George Shen <[email protected]>
George Shen 2 ani în urmă
părinte
comite
55c9e97cab
3 a modificat fișierele cu 46 adăugiri și 12 ștergeri
  1. 15 3
      msm/eva/msm_cvp_buf.c
  2. 30 9
      msm/eva/msm_cvp_dsp.c
  3. 1 0
      msm/eva/msm_cvp_internal.h

+ 15 - 3
msm/eva/msm_cvp_buf.c

@@ -329,6 +329,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf)
 		goto exit;
 	}
 
+	atomic_inc(&smem->refcount);
 	cbuf->smem = smem;
 	cbuf->fd = buf->fd;
 	cbuf->size = buf->size;
@@ -383,18 +384,25 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf)
 			break;
 		}
 	}
-	mutex_unlock(&inst->cvpdspbufs.lock);
 	if (!found) {
+		mutex_unlock(&inst->cvpdspbufs.lock);
 		print_client_buffer(CVP_ERR, "invalid", inst, buf);
 		return -EINVAL;
 	}
 
 	if (cbuf->smem->device_addr) {
+		u64 idx = inst->unused_dsp_bufs.ktid;
+		inst->unused_dsp_bufs.smem[idx] = *(cbuf->smem);
+		inst->unused_dsp_bufs.nr++;
+		inst->unused_dsp_bufs.nr =
+			(inst->unused_dsp_bufs.nr > MAX_FRAME_BUFFER_NUMS)?
+			MAX_FRAME_BUFFER_NUMS : inst->unused_dsp_bufs.nr;
+		inst->unused_dsp_bufs.ktid = ++idx % MAX_FRAME_BUFFER_NUMS;
+
 		msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp");
 		msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf);
+		atomic_dec(&cbuf->smem->refcount);
 	}
-
-	mutex_lock(&inst->cvpdspbufs.lock);
 	list_del(&cbuf->list);
 	mutex_unlock(&inst->cvpdspbufs.lock);
 
@@ -1957,6 +1965,10 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log)
 	for (i = 0; i < inst->unused_wncc_bufs.nr; i++)
 		_log_smem(snap, inst, &inst->unused_wncc_bufs.smem[i], log);
 
+	dprintk(CVP_ERR, "unmapped dsp bufs\n");
+	for (i = 0; i < inst->unused_dsp_bufs.nr; i++)
+		_log_smem(snap, inst, &inst->unused_dsp_bufs.smem[i], log);
+
 }
 
 struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst,

+ 30 - 9
msm/eva/msm_cvp_dsp.c

@@ -1430,8 +1430,10 @@ exit:
 	mutex_unlock(&device->lock);
 }
 /* 32 or 64 bit CPU Side Ptr <-> 2 32 bit DSP Pointers. Dirty Fix. */
-static void *ptr_dsp2cpu(uint32_t session_cpu_high, uint32_t session_cpu_low)
+static void *get_inst_from_dsp(uint32_t session_cpu_high, uint32_t session_cpu_low)
 {
+	struct msm_cvp_core *core;
+	struct msm_cvp_inst *sess_inst;
 	void *inst;
 
 	if ((session_cpu_high == 0) && (sizeof(void *) == BITPTRSIZE32)) {
@@ -1444,7 +1446,26 @@ static void *ptr_dsp2cpu(uint32_t session_cpu_high, uint32_t session_cpu_low)
 			"%s Invalid _cpu_high = 0x%x _cpu_low = 0x%x\n",
 				__func__, session_cpu_high, session_cpu_low);
 		inst = NULL;
+		return inst;
 	}
+
+	core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
+	if (core) {
+		mutex_lock(&core->lock);
+		list_for_each_entry(sess_inst, &core->instances, list) {
+			if (sess_inst->session_type == MSM_CVP_DSP) {
+				if (sess_inst == (struct msm_cvp_inst *)inst) {
+					mutex_unlock(&core->lock);
+					return inst;
+				}
+			}
+		}
+		mutex_unlock(&core->lock);
+		inst = NULL;
+	} else {
+		return NULL;
+	}
+
 	return inst;
 }
 
@@ -1602,7 +1623,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd)
 	}
 
 	cvp_put_fastrpc_node(frpc_node);
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 	if (!inst || !is_cvp_inst_valid(inst)) {
@@ -1658,7 +1679,7 @@ static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd)
 		dsp2cpu_cmd->session_cpu_low,
 		dsp2cpu_cmd->session_cpu_high);
 
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 
@@ -1725,7 +1746,7 @@ static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd)
 		return;
 	}
 
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 
@@ -1783,7 +1804,7 @@ static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd)
 		return;
 	}
 
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 
@@ -1840,7 +1861,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd)
 	}
 	frpc_device = frpc_node->cvp_fastrpc_device;
 
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 
@@ -1916,7 +1937,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd)
 		dsp2cpu_cmd->session_cpu_high,
 		dsp2cpu_cmd->pid);
 
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 	if (!inst) {
@@ -1999,7 +2020,7 @@ static void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd)
 		dsp2cpu_cmd->session_cpu_high,
 		dsp2cpu_cmd->pid);
 
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 
@@ -2028,7 +2049,7 @@ static void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd)
 		dsp2cpu_cmd->session_cpu_high,
 		dsp2cpu_cmd->pid);
 
-	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 

+ 1 - 0
msm/eva/msm_cvp_internal.h

@@ -385,6 +385,7 @@ struct msm_cvp_inst {
 	struct msm_cvp_list cvpwnccbufs;
 	struct msm_cvp_list frames;
 	struct cvp_frame_bufs last_frame;
+	struct cvp_frame_bufs unused_dsp_bufs;
 	struct cvp_frame_bufs unused_wncc_bufs;
 	u32 cvpwnccbufs_num;
 	struct msm_cvp_wncc_buffer* cvpwnccbufs_table;