Procházet zdrojové kódy

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 před 1 rokem
rodič
revize
20bfba635c
3 změnil soubory, kde provedl 52 přidání a 22 odebrání
  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 msm_cvp_inst *s;
 	struct cvp_hfi_ops *ops_tbl;
-	int rc;
+	int rc = 0;
+	int curr_sq_state = -1;
 
 	if (!inst || !inst->core) {
 		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
@@ -942,8 +943,27 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 		return -ECONNRESET;
 
 	sq = &inst->session_queue;
+	curr_sq_state = sq->state;
 
 	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) {
 		dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n",
 			sq->msg_count);
@@ -965,6 +985,9 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 	if (rc) {
 		dprintk(CVP_WARN, "%s: session stop failed rc %d\n",
 				__func__, rc);
+		spin_lock(&sq->lock);
+		sq->state = curr_sq_state;
+		spin_unlock(&sq->lock);
 		goto stop_thread;
 	}
 
@@ -973,6 +996,9 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 	if (rc) {
 		dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n",
 				__func__, rc);
+		spin_lock(&sq->lock);
+		sq->state = curr_sq_state;
+		spin_unlock(&sq->lock);
 		goto stop_thread;
 	}
 
@@ -998,8 +1024,6 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst)
 		return 0;
 	}
 
-	sq->state = QUEUE_STOP;
-
 	dprintk(CVP_SESS, "Stop session queue: %pK session_id = %#x\n",
 			inst, hash32_ptr(inst->session));
 	spin_unlock(&sq->lock);

+ 16 - 1
msm/eva/msm_cvp_core.c

@@ -359,6 +359,16 @@ stop_session:
 			__func__, inst);
 		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) {
 		/* STOP SESSION to avoid SMMU fault after releasing ARP */
 		ops_tbl = inst->core->dev_ops;
@@ -371,9 +381,14 @@ stop_session:
 
 		/*Fail stop session, release arp later may cause smmu fault*/
 		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",
 					__func__, rc);
+		} else {
+			spin_lock(&sq->lock);
+			sq->state = QUEUE_STOP;
+			spin_unlock(&sq->lock);
+		}
 		/* Continue to release ARP anyway */
 	}
 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;
 
 	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,
 		dsp2cpu_cmd->session_cpu_low,
 		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(
 			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 msm_cvp_inst *inst;
-	struct cvp_session_queue *sq;
 	int rc;
 	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 
 	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(
 			dsp2cpu_cmd->session_cpu_high,
 			dsp2cpu_cmd->session_cpu_low);
@@ -1991,14 +1984,12 @@ void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd)
 		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);
 	if (rc) {