mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
msm: camera: cdm: handle dead lock scenario
This change handles a race condition in which cdm workqueue is scheduled on one of the cores and cdm flush is executing on another core. We come across a dead lock between fifo_lock and hw_mutex lock. CRs-Fixed: 3049531 Change-Id: Ie0b8982a7e55218fc5655f8e3d08a952fd852ed7 Signed-off-by: Vikram Sharma <vikramsa@codeaurora.org>
This commit is contained in:
parent
981b2405f2
commit
7f25abfda5
2 changed files with 6 additions and 6 deletions
|
|
@ -180,12 +180,10 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
(struct cam_cdm_bl_cb_request_entry *)data;
|
||||
|
||||
client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl);
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
client = core->clients[client_idx];
|
||||
if ((!client) || (client->handle != node->client_hdl)) {
|
||||
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
|
||||
node->client_hdl);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
return;
|
||||
}
|
||||
cam_cdm_get_client_refcount(client);
|
||||
|
|
@ -204,7 +202,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
}
|
||||
mutex_unlock(&client->lock);
|
||||
cam_cdm_put_client_refcount(client);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
return;
|
||||
} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
|
||||
status == CAM_CDM_CB_STATUS_HW_FLUSH ||
|
||||
|
|
@ -242,7 +239,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
|
||||
for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) {
|
||||
if (core->clients[i] != NULL) {
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
client = core->clients[i];
|
||||
cam_cdm_get_client_refcount(client);
|
||||
mutex_lock(&client->lock);
|
||||
|
|
@ -265,7 +261,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
}
|
||||
mutex_unlock(&client->lock);
|
||||
cam_cdm_put_client_refcount(client);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1238,6 +1238,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
mutex_lock(&core->bl_fifo[fifo_idx].fifo_lock);
|
||||
|
||||
if (atomic_read(&core->bl_fifo[fifo_idx].work_record))
|
||||
|
|
@ -1251,6 +1252,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
|
|||
core->arbitration);
|
||||
mutex_unlock(&core->bl_fifo[fifo_idx]
|
||||
.fifo_lock);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1289,6 +1291,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
|
|||
}
|
||||
mutex_unlock(&core->bl_fifo[payload->fifo_idx]
|
||||
.fifo_lock);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
}
|
||||
|
||||
if (payload->irq_status &
|
||||
|
|
@ -1405,9 +1408,9 @@ handle_cdm_pf:
|
|||
cdm_hw->soc_info.index);
|
||||
for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++)
|
||||
mutex_unlock(&core->bl_fifo[i].fifo_lock);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
|
||||
(void *)pf_info->iova);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
clear_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
|
||||
} else {
|
||||
CAM_ERR(CAM_CDM, "Invalid token");
|
||||
|
|
@ -1806,9 +1809,11 @@ int cam_hw_cdm_handle_error_info(
|
|||
|
||||
if (node != NULL) {
|
||||
if (node->request_type == CAM_HW_CDM_BL_CB_CLIENT) {
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
cam_cdm_notify_clients(cdm_hw,
|
||||
CAM_CDM_CB_STATUS_HW_ERROR,
|
||||
(void *)node);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
} else if (node->request_type == CAM_HW_CDM_BL_CB_INTERNAL) {
|
||||
CAM_ERR(CAM_CDM, "Invalid node=%pK %d", node,
|
||||
node->request_type);
|
||||
|
|
|
|||
Loading…
Reference in a new issue