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) {