From 20bfba635c23c9a23106f59526421d9d3ba9faeb Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Wed, 13 Dec 2023 10:22:58 +0530 Subject: [PATCH] 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 --- msm/eva/msm_cvp.c | 30 +++++++++++++++++++++++++++--- msm/eva/msm_cvp_core.c | 17 ++++++++++++++++- msm/eva/msm_cvp_dsp.c | 27 +++++++++------------------ 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 87b6de6c89..f30b6e929a 100644 --- a/msm/eva/msm_cvp.c +++ b/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); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 74d03c21a4..5a8d3039d5 100644 --- a/msm/eva/msm_cvp_core.c +++ b/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: diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index c5a605c117..a3300ca886 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/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) {