Pārlūkot izejas kodu

msm: eva: Session queue state check before calling stop session

To avoid calling stop session twice, we need to check the state
before calling the stop session. Failing this will result in
incorrect cmd sequence error(0x1026) from FW.

Change-Id: I01c8325881952e5152799c62daebd622933667b2
Signed-off-by: Aniruddh Sharma <[email protected]>
Aniruddh Sharma 1 gadu atpakaļ
vecāks
revīzija
20bfba635c
3 mainītis faili ar 52 papildinājumiem un 22 dzēšanām
  1. 27 3
      msm/eva/msm_cvp.c
  2. 16 1
      msm/eva/msm_cvp_core.c
  3. 9 18
      msm/eva/msm_cvp_dsp.c

+ 27 - 3
msm/eva/msm_cvp.c

@@ -927,7 +927,8 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 	struct eva_kmd_session_control *sc = NULL;
 	struct eva_kmd_session_control *sc = NULL;
 	struct msm_cvp_inst *s;
 	struct msm_cvp_inst *s;
 	struct cvp_hfi_ops *ops_tbl;
 	struct cvp_hfi_ops *ops_tbl;
-	int rc;
+	int rc = 0;
+	int curr_sq_state = -1;
 
 
 	if (!inst || !inst->core) {
 	if (!inst || !inst->core) {
 		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
 		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
@@ -942,8 +943,27 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 		return -ECONNRESET;
 		return -ECONNRESET;
 
 
 	sq = &inst->session_queue;
 	sq = &inst->session_queue;
+	curr_sq_state = sq->state;
 
 
 	spin_lock(&sq->lock);
 	spin_lock(&sq->lock);
+	if (sq->state != QUEUE_START) {
+		spin_unlock(&sq->lock);
+		dprintk(CVP_ERR,
+			"%s: Stop not allowed - curr state %d,  inst %llx, sess %llx, %s type %d\n",
+			__func__, sq->state, inst, inst->session, inst->proc_name,
+			inst->session_type);
+		rc = -EINVAL;
+		return rc;
+	}
+
+	if (sq->state == QUEUE_STOP) {
+		spin_unlock(&sq->lock);
+		dprintk(CVP_WARN,
+				"%s: Double stop session - inst %llx, sess %llx, %s of type %d\n",
+				__func__, inst, inst->session, inst->proc_name, inst->session_type);
+		return rc;
+	}
+
 	if (sq->msg_count) {
 	if (sq->msg_count) {
 		dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n",
 		dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n",
 			sq->msg_count);
 			sq->msg_count);
@@ -965,6 +985,9 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 	if (rc) {
 	if (rc) {
 		dprintk(CVP_WARN, "%s: session stop failed rc %d\n",
 		dprintk(CVP_WARN, "%s: session stop failed rc %d\n",
 				__func__, rc);
 				__func__, rc);
+		spin_lock(&sq->lock);
+		sq->state = curr_sq_state;
+		spin_unlock(&sq->lock);
 		goto stop_thread;
 		goto stop_thread;
 	}
 	}
 
 
@@ -973,6 +996,9 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 	if (rc) {
 	if (rc) {
 		dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n",
 		dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n",
 				__func__, rc);
 				__func__, rc);
+		spin_lock(&sq->lock);
+		sq->state = curr_sq_state;
+		spin_unlock(&sq->lock);
 		goto stop_thread;
 		goto stop_thread;
 	}
 	}
 
 
@@ -998,8 +1024,6 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst)
 		return 0;
 		return 0;
 	}
 	}
 
 
-	sq->state = QUEUE_STOP;
-
 	dprintk(CVP_SESS, "Stop session queue: %pK session_id = %#x\n",
 	dprintk(CVP_SESS, "Stop session queue: %pK session_id = %#x\n",
 			inst, hash32_ptr(inst->session));
 			inst, hash32_ptr(inst->session));
 	spin_unlock(&sq->lock);
 	spin_unlock(&sq->lock);

+ 16 - 1
msm/eva/msm_cvp_core.c

@@ -359,6 +359,16 @@ stop_session:
 			__func__, inst);
 			__func__, inst);
 		goto exit;
 		goto exit;
 	}
 	}
+	spin_lock(&sq->lock);
+	if (sq->state == QUEUE_STOP) {
+		spin_unlock(&sq->lock);
+		dprintk(CVP_WARN,
+			"%s: Double stop session - inst %llx, sess %llx, %s of type %d\n",
+			__func__, inst, inst->session, inst->proc_name, inst->session_type);
+		goto release_arp;
+	}
+	spin_unlock(&sq->lock);
+
 	if (!empty) {
 	if (!empty) {
 		/* STOP SESSION to avoid SMMU fault after releasing ARP */
 		/* STOP SESSION to avoid SMMU fault after releasing ARP */
 		ops_tbl = inst->core->dev_ops;
 		ops_tbl = inst->core->dev_ops;
@@ -371,9 +381,14 @@ stop_session:
 
 
 		/*Fail stop session, release arp later may cause smmu fault*/
 		/*Fail stop session, release arp later may cause smmu fault*/
 		rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_STOP_DONE);
 		rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_STOP_DONE);
-		if (rc)
+		if (rc) {
 			dprintk(CVP_WARN, "%s: wait for sess_stop fail, rc %d\n",
 			dprintk(CVP_WARN, "%s: wait for sess_stop fail, rc %d\n",
 					__func__, rc);
 					__func__, rc);
+		} else {
+			spin_lock(&sq->lock);
+			sq->state = QUEUE_STOP;
+			spin_unlock(&sq->lock);
+		}
 		/* Continue to release ARP anyway */
 		/* Continue to release ARP anyway */
 	}
 	}
 release_arp:
 release_arp:

+ 9 - 18
msm/eva/msm_cvp_dsp.c

@@ -1846,11 +1846,12 @@ void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd)
 	cmd->ret = 0;
 	cmd->ret = 0;
 
 
 	dprintk(CVP_DSP,
 	dprintk(CVP_DSP,
-		"%s sess id 0x%x, low 0x%x, high 0x%x, hnl 0x%x\n",
+		"%s sess 0x%x, low 0x%x, high 0x%x, hnl 0x%x, iova 0x%x, fd 0x%x\n",
 		__func__, dsp2cpu_cmd->session_id,
 		__func__, dsp2cpu_cmd->session_id,
 		dsp2cpu_cmd->session_cpu_low,
 		dsp2cpu_cmd->session_cpu_low,
 		dsp2cpu_cmd->session_cpu_high,
 		dsp2cpu_cmd->session_cpu_high,
-		dsp2cpu_cmd->pid);
+		dsp2cpu_cmd->pid, dsp2cpu_cmd->sbuf.iova,
+		dsp2cpu_cmd->sbuf.fd);
 
 
 	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_high,
@@ -1968,19 +1969,11 @@ void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd)
 {
 {
 	struct cvp_dsp_apps *me = &gfa_cv;
 	struct cvp_dsp_apps *me = &gfa_cv;
 	struct msm_cvp_inst *inst;
 	struct msm_cvp_inst *inst;
-	struct cvp_session_queue *sq;
 	int rc;
 	int rc;
 	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 
 
 	cmd->ret = 0;
 	cmd->ret = 0;
 
 
-	dprintk(CVP_DSP,
-		"%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n",
-		__func__, dsp2cpu_cmd->session_id,
-		dsp2cpu_cmd->session_cpu_low,
-		dsp2cpu_cmd->session_cpu_high,
-		dsp2cpu_cmd->pid);
-
 	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 	inst = (struct msm_cvp_inst *)get_inst_from_dsp(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
 			dsp2cpu_cmd->session_cpu_low);
@@ -1991,14 +1984,12 @@ void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd)
 		return;
 		return;
 	}
 	}
 
 
-	sq = &inst->session_queue;
-	spin_lock(&sq->lock);
-	if (sq->state == QUEUE_STOP) {
-		spin_unlock(&sq->lock);
-		dprintk(CVP_WARN, "DSP double stopped session %llx\n", inst);
-		return;
-	}
-	spin_unlock(&sq->lock);
+	dprintk(CVP_DSP,
+		"%s sess id 0x%x low 0x%x high 0x%x, pid 0x%x, inst_kref_refcount 0x%x\n",
+		__func__, dsp2cpu_cmd->session_id,
+		dsp2cpu_cmd->session_cpu_low,
+		dsp2cpu_cmd->session_cpu_high,
+		dsp2cpu_cmd->pid, kref_read(&inst->kref));
 
 
 	rc = msm_cvp_session_stop(inst, (struct eva_kmd_arg *)NULL);
 	rc = msm_cvp_session_stop(inst, (struct eva_kmd_arg *)NULL);
 	if (rc) {
 	if (rc) {