From e30e31d72be01a67bf447245ebdf8b15f53ac85b Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 1 Aug 2022 14:49:13 -0700 Subject: [PATCH] msm: eva: fix DSP session deletion racing The racing to delete DSP session may happen after DSP SSR when EVA DSP driver just sent session deletion command to CPU driver. Change-Id: I252000bc2c04148874db02b50d0a94c10edbb6e6 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 2 ++ msm/eva/msm_cvp_dsp.c | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index a0ccd09613..73c32b7816 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1833,6 +1833,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, goto err_no_mem; } buf->smem->pkt_type = buf->smem->buf_idx = 0; + atomic_inc(&buf->smem->refcount); dprintk(CVP_MEM, "%s dma_buf %pK\n", __func__, buf->smem->dma_buf); @@ -1875,6 +1876,7 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, "%s: %x : fd %x %s size %d", __func__, hash32_ptr(inst->session), buf->fd, smem->dma_buf->name, buf->size); + atomic_dec(&smem->refcount); msm_cvp_smem_free(smem); kmem_cache_free(cvp_driver->smem_cache, smem); } else { diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index ffc5996c45..940f5b027e 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -341,15 +341,33 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct msm_cvp_inst *inst = NULL; struct list_head *s = NULL, *next_s = NULL; + u32 max_num_retries = 100; dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__); + mutex_lock(&me->rx_lock); + while (max_num_retries > 0) { + if (me->pending_dsp2cpu_cmd.type != + CVP_INVALID_RPMSG_TYPE) { + mutex_unlock(&me->rx_lock); + usleep_range(1000, 5000); + mutex_lock(&me->rx_lock); + } else { + break; + } + max_num_retries--; + } + + if (!max_num_retries) + dprintk(CVP_ERR, "stuck processing pending DSP cmds\n"); + mutex_lock(&me->tx_lock); cvp_hyp_assign_from_dsp(); me->chan = NULL; me->state = DSP_UNINIT; mutex_unlock(&me->tx_lock); + mutex_unlock(&me->rx_lock); while ((frpc_node = dequeue_frpc_node())) { s = &frpc_node->dsp_sessions.list; @@ -1819,8 +1837,6 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) mutex_lock(&buf_list->lock); list_for_each_safe(ptr, next, &buf_list->list) { buf = list_entry(ptr, struct cvp_internal_buf, list); - dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n", - buf->fd, dsp2cpu_cmd->sbuf.fd); if (!buf->smem) { dprintk(CVP_DSP, "Empyt smem\n"); @@ -1831,6 +1847,8 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) if (buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) { dprintk(CVP_DSP, "%s find device addr 0x%x\n", __func__, buf->smem->device_addr); + dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n", + buf->fd, dsp2cpu_cmd->sbuf.fd); rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); if (rc) { @@ -1905,6 +1923,11 @@ wait_dsp: dprintk(CVP_WARN, "%s received interrupt signal\n", __func__); } else { mutex_lock(&me->rx_lock); + if (me->state == DSP_UNINIT) { + /* DSP SSR may have happened */ + mutex_unlock(&me->rx_lock); + goto wait_dsp; + } switch (me->pending_dsp2cpu_cmd.type) { case DSP2CPU_POWERON: {