瀏覽代碼

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

Camera Software Integration 4 年之前
父節點
當前提交
dc33d7705c
共有 1 個文件被更改,包括 73 次插入20 次删除
  1. 73 20
      drivers/cam_req_mgr/cam_req_mgr_core.c

+ 73 - 20
drivers/cam_req_mgr/cam_req_mgr_core.c

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