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 <nitegupt@codeaurora.org>
Signed-off-by: Gauri Joshi <gaurjosh@codeaurora.org>
This commit is contained in:
Nitesh Gupta 2021-03-01 09:31:13 +05:30 • committed by Gauri Joshi
commit fa2304691b

View file

@ -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;
}