From fa2304691b1be4e4ae7bf5f33af5bc6eb486eb1e Mon Sep 17 00:00:00 2001 From: Nitesh Gupta Date: Mon, 1 Mar 2021 09:31:13 +0530 Subject: [PATCH] msm: mhi_dev: Handle potential deadlock situation With the current logic, MHI driver will hold channel lock while processing the ring element and triggers callback for the clients. Some clients are issuing read requests for the channel in the callback context. MHI driver will try to acquire the same channel lock in read api leading to a deadlock situation. Modify the logic to avoid holding channel lock while processing the ring elements. Change-Id: I62ac28d5eb06e3c9b12437f02288cfe1cdb2bea2 Signed-off-by: Nitesh Gupta Signed-off-by: Gauri Joshi --- drivers/platform/msm/mhi_dev/mhi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index 46ba74e89570..80320c19045e 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -2171,15 +2171,14 @@ static void mhi_dev_process_ring_pending(struct work_struct *work) } ch = &mhi->ch[ring->id - mhi->ch_ring_start]; - mutex_lock(&ch->ch_lock); rc = mhi_dev_process_ring(ring); if (rc) { mhi_log(MHI_MSG_ERROR, "error processing ring %d\n", ring->id); - mutex_unlock(&ch->ch_lock); goto exit; } + mutex_lock(&ch->ch_lock); ch->db_pending = false; if (ch->reset_pending) { @@ -3262,9 +3261,9 @@ int mhi_dev_read_channel(struct mhi_req *mreq) mutex_lock(&ch->ch_lock); do { - if (ch->state == MHI_DEV_CH_STOPPED) { + if (ch->state == MHI_DEV_CH_STOPPED || ch->reset_pending) { mhi_log(MHI_MSG_VERBOSE, - "channel (%d) already stopped\n", + "channel (%d) already stopped or RST pending\n", mreq->chan); bytes_read = -1; goto exit; @@ -3445,9 +3444,10 @@ int mhi_dev_write_channel(struct mhi_req *wreq) } ch->pend_wr_count++; - if (ch->state == MHI_DEV_CH_STOPPED) { + if (ch->state == MHI_DEV_CH_STOPPED || ch->reset_pending) { mhi_log(MHI_MSG_ERROR, - "channel %d already stopped\n", wreq->chan); + "channel %d already stopped or RST pending\n", + wreq->chan); bytes_written = -1; goto exit; }