Merge "msm: camera: reqmgr: Add protection while destroying the link" into camera-kernel.lnx.4.0

Esse commit está contido em:
Camera Software Integration
2020-10-28 13:28:03 -07:00
commit de Gerrit - the friendly Code Review server

Ver arquivo

@@ -314,6 +314,10 @@ static int __cam_req_mgr_notify_error_on_link(
int rc = 0, pd;
session = (struct cam_req_mgr_core_session *)link->parent;
if (!session) {
CAM_WARN(CAM_CRM, "session ptr NULL %x", link->link_hdl);
return -EINVAL;
}
pd = dev->dev_info.p_delay;
if (pd >= CAM_PIPELINE_DELAY_MAX) {
@@ -1112,12 +1116,19 @@ static int __cam_req_mgr_check_sync_for_mslave(
int64_t req_id = 0, sync_req_id = 0;
int32_t sync_num_slots = 0;
if (!sync_link) {
CAM_ERR(CAM_CRM, "Sync link null");
if (!sync_link || !link) {
CAM_ERR(CAM_CRM, "Sync link or link is null");
return -EINVAL;
}
req_id = slot->req_id;
if (!sync_link->req.in_q) {
CAM_ERR(CAM_CRM, "Link hdl %x in_q is NULL",
sync_link->link_hdl);
return -EINVAL;
}
sync_num_slots = sync_link->req.in_q->num_slots;
sync_rd_idx = sync_link->req.in_q->rd_idx;
@@ -1185,7 +1196,6 @@ static int __cam_req_mgr_check_sync_for_mslave(
(sync_link->initial_sync_req <= sync_req_id)) {
sync_slot_idx = __cam_req_mgr_find_slot_for_req(
sync_link->req.in_q, sync_req_id);
if (sync_slot_idx == -1) {
CAM_DBG(CAM_CRM,
"Prev Req: %lld [master] not found on link: %x [slave]",
@@ -1319,20 +1329,27 @@ static int __cam_req_mgr_check_sync_req_is_ready(
uint64_t master_slave_diff = 0;
bool ready = true, sync_ready = true;
if (!sync_link) {
if (!sync_link || !link) {
CAM_ERR(CAM_CRM, "Sync link null");
return -EINVAL;
}
req_id = slot->req_id;
if (!sync_link->req.in_q) {
CAM_ERR(CAM_CRM, "Link hdl %x in_q is NULL",
sync_link->link_hdl);
return -EINVAL;
}
sync_num_slots = sync_link->req.in_q->num_slots;
sync_rd_idx = sync_link->req.in_q->rd_idx;
sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx];
sync_req_id = sync_rd_slot->req_id;
sync_rd_idx = sync_link->req.in_q->rd_idx;
sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx];
sync_req_id = sync_rd_slot->req_id;
CAM_DBG(CAM_REQ,
"link_hdl %x req %lld frame_skip_flag %d ",
link->link_hdl, req_id, link->sync_link_sof_skip);
"link_hdl %x sync link_hdl %x req %lld",
link->link_hdl, sync_link->link_hdl, req_id);
if (sync_link->initial_skip) {
link->initial_skip = false;
@@ -1436,13 +1453,20 @@ static int __cam_req_mgr_check_sync_req_is_ready(
ready = false;
}
rc = __cam_req_mgr_check_link_is_ready(sync_link, sync_slot_idx, true);
if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
"Req: %lld not ready on [other link] link: %x, rc=%d",
req_id, sync_link->link_hdl, rc);
sync_ready = false;
if (sync_link->req.in_q) {
rc = __cam_req_mgr_check_link_is_ready(sync_link,
sync_slot_idx, true);
if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
"Req: %lld not ready on link: %x, rc=%d",
req_id, sync_link->link_hdl, rc);
sync_ready = false;
}
} else {
CAM_ERR(CAM_CRM, "Link hdl %x in_q is NULL",
sync_link->link_hdl);
return -EINVAL;
}
/*
@@ -1508,7 +1532,6 @@ static int __cam_req_mgr_check_sync_req_is_ready(
return -EAGAIN;
}
}
CAM_DBG(CAM_REQ,
"Req: %lld ready to apply on link: %x [validation successful]",
req_id, link->link_hdl);
@@ -1522,8 +1545,20 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
{
int i, rc = 0;
if (link->state == CAM_CRM_LINK_STATE_IDLE) {
CAM_ERR(CAM_CRM, "link hdl %x is in idle state",
link->link_hdl);
return -EINVAL;
}
for (i = 0; i < link->num_sync_links; i++) {
if (link->sync_link[i]) {
if (link->sync_link[i]->state ==
CAM_CRM_LINK_STATE_IDLE) {
CAM_ERR(CAM_CRM, "sync link hdl %x is idle",
link->sync_link[i]->link_hdl);
return -EINVAL;
}
if (link->max_delay == link->sync_link[i]->max_delay) {
rc = __cam_req_mgr_check_sync_req_is_ready(
link, link->sync_link[i], slot);
@@ -1554,6 +1589,9 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
return rc;
}
}
} else {
CAM_ERR(CAM_REQ, "Sync link is null");
return -EINVAL;
}
}
@@ -1593,9 +1631,14 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
struct cam_req_mgr_core_link *tmp_link = NULL;
uint32_t max_retry = 0;
in_q = link->req.in_q;
session = (struct cam_req_mgr_core_session *)link->parent;
if (!session) {
CAM_WARN(CAM_CRM, "session ptr NULL %x", link->link_hdl);
return -EINVAL;
}
mutex_lock(&session->lock);
in_q = link->req.in_q;
/*
* Check if new read index,
* - if in pending state, traverse again to complete
@@ -2012,6 +2055,10 @@ static int __cam_req_mgr_process_sof_freeze(void *priv, void *data)
link = (struct cam_req_mgr_core_link *)priv;
session = (struct cam_req_mgr_core_session *)link->parent;
if (!session) {
CAM_WARN(CAM_CRM, "session ptr NULL %x", link->link_hdl);
return -EINVAL;
}
spin_lock_bh(&link->link_state_spin_lock);
if ((link->watchdog) && (link->watchdog->pause_timer)) {
@@ -2274,6 +2321,7 @@ static void __cam_req_mgr_free_link(struct cam_req_mgr_core_link *link)
ptrdiff_t i;
kfree(link->req.in_q);
link->req.in_q = NULL;
link->parent = NULL;
i = link - g_links;
CAM_DBG(CAM_CRM, "free link index %d", i);
cam_req_mgr_core_link_reset(link);
@@ -2834,7 +2882,8 @@ static int cam_req_mgr_process_trigger(void *priv, void *data)
spin_lock_bh(&link->link_state_spin_lock);
if (link->state < CAM_CRM_LINK_STATE_READY) {
CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
CAM_WARN(CAM_CRM, "invalid link state:%d for link 0x%x",
link->state, link->link_hdl);
spin_unlock_bh(&link->link_state_spin_lock);
rc = -EPERM;
goto release_lock;
@@ -3617,6 +3666,7 @@ int cam_req_mgr_destroy_session(
goto end;
}
mutex_lock(&cam_session->lock);
if (cam_session->num_links) {
CAM_DBG(CAM_CRM, "destroy session %x num_active_links %d",
ses_info->session_hdl,
@@ -3624,10 +3674,11 @@ int cam_req_mgr_destroy_session(
for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) {
link = cam_session->links[i];
if (!link)
continue;
CAM_DBG(CAM_CRM, "Unlink link hdl 0x%x",
link->link_hdl);
/* Ignore return value since session is going away */
link->is_shutdown = is_shutdown;
__cam_req_mgr_unlink(link);
@@ -3635,7 +3686,9 @@ int cam_req_mgr_destroy_session(
}
}
list_del(&cam_session->entry);
mutex_unlock(&cam_session->lock);
mutex_destroy(&cam_session->lock);
kfree(cam_session);
rc = cam_destroy_session_hdl(ses_info->session_hdl);