Răsfoiți Sursa

msm: camera: icp: Add LDAR support for wait and pending lists

When LDAR dump is triggered check for any remaining buffers in all
possible buffer lists in the ICP, in case of found buffers add their
info to the LDAR Dump.

CRs-Fixed: 3298809
Change-Id: I55d3780c7d789e3a77e78c9ef3ecffc9a36419f3
Signed-off-by: Petar Ivanov <[email protected]>
Petar Ivanov 2 ani în urmă
părinte
comite
94a49971d2
1 a modificat fișierele cu 78 adăugiri și 24 ștergeri
  1. 78 24
      drivers/cam_core/cam_context_utils.c

+ 78 - 24
drivers/cam_core/cam_context_utils.c

@@ -1426,7 +1426,7 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	struct cam_hw_dump_args *dump_args)
 {
 	int                              rc, i;
-	struct cam_ctx_request          *req, *req_temp;
+	struct cam_ctx_request          *req = NULL, *req_temp;
 	struct cam_context_dump_header  *hdr;
 	uint8_t                         *dst;
 	uint64_t                        *addr, *start;
@@ -1440,20 +1440,9 @@ static int cam_context_user_dump(struct cam_context *ctx,
 		return -EINVAL;
 	}
 
-	spin_lock_bh(&ctx->lock);
-	if (list_empty(&ctx->active_req_list)) {
-		CAM_ERR(CAM_CTXT, "[%s][%d] no active request",
-			ctx->dev_name, ctx->ctx_id);
-		spin_unlock_bh(&ctx->lock);
-		return 0;
-	}
-
-	req = list_first_entry(&ctx->active_req_list,
-		struct cam_ctx_request, list);
-	spin_unlock_bh(&ctx->lock);
-
 	rc = cam_mem_get_cpu_buf(dump_args->buf_handle,
 		&cpu_addr, &buf_len);
+
 	if (rc) {
 		CAM_ERR(CAM_CTXT, "Invalid hdl %u rc %d",
 			dump_args->buf_handle, rc);
@@ -1466,15 +1455,34 @@ static int cam_context_user_dump(struct cam_context *ctx,
 		return -ENOSPC;
 	}
 
-	remain_len = buf_len - dump_args->offset;
-	min_len = sizeof(struct cam_context_dump_header) +
-		(CAM_CTXT_DUMP_NUM_WORDS + req->num_in_map_entries +
-		(req->num_out_map_entries * 2)) * sizeof(uint64_t);
+	spin_lock_bh(&ctx->lock);
+	if (!list_empty(&ctx->active_req_list)) {
+		req = list_first_entry(&ctx->active_req_list,
+			struct cam_ctx_request, list);
+	} else if (!list_empty(&ctx->wait_req_list)) {
+		req = list_first_entry(&ctx->wait_req_list,
+			struct cam_ctx_request, list);
+	} else if (!list_empty(&ctx->pending_req_list)) {
+		req = list_first_entry(&ctx->pending_req_list,
+			struct cam_ctx_request, list);
+	} else {
+		CAM_ERR(CAM_CTXT, "[%s][%d] no request to dump",
+			ctx->dev_name, ctx->ctx_id);
+	}
+	spin_unlock_bh(&ctx->lock);
 
-	if (remain_len < min_len) {
-		CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u",
-			remain_len, min_len);
-		return -ENOSPC;
+	/* Check for min len in case of available request to dump */
+	if (req != NULL) {
+		remain_len = buf_len - dump_args->offset;
+		min_len = sizeof(struct cam_context_dump_header) +
+			(CAM_CTXT_DUMP_NUM_WORDS + req->num_in_map_entries +
+			(req->num_out_map_entries * 2)) * sizeof(uint64_t);
+
+		if (remain_len < min_len) {
+			CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u",
+				remain_len, min_len);
+			return -ENOSPC;
+		}
 	}
 
 	/* Dump context info */
@@ -1505,7 +1513,7 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	hdr->word_size = sizeof(uint64_t);
 	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
 	start = addr;
-	if (!list_empty(&ctx->wait_req_list)) {
+	if (!list_empty(&ctx->pending_req_list)) {
 		list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
 			*addr++ = req->request_id;
 		}
@@ -1515,7 +1523,7 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	dump_args->offset += hdr->size +
 		sizeof(struct cam_context_dump_header);
 
-	/* Dump applied request IDs */
+	/* Dump wait request IDs */
 	dst = (uint8_t *)cpu_addr + dump_args->offset;
 	hdr = (struct cam_context_dump_header *)dst;
 	scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
@@ -1523,7 +1531,7 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	hdr->word_size = sizeof(uint64_t);
 	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
 	start = addr;
-	if (!list_empty(&ctx->pending_req_list)) {
+	if (!list_empty(&ctx->wait_req_list)) {
 		list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
 			*addr++ = req->request_id;
 		}
@@ -1551,6 +1559,52 @@ static int cam_context_user_dump(struct cam_context *ctx,
 	dump_args->offset += hdr->size +
 		sizeof(struct cam_context_dump_header);
 
+	/* Dump waiting requests */
+	if (!list_empty(&ctx->wait_req_list)) {
+		list_for_each_entry_safe(req, req_temp, &ctx->wait_req_list, list) {
+			for (i = 0; i < req->num_out_map_entries; i++) {
+				dst = (uint8_t *)cpu_addr + dump_args->offset;
+				hdr = (struct cam_context_dump_header *)dst;
+				scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
+					"%s_OUT_FENCE_REQUEST_APPLIED.%d.%d.%d:",
+					ctx->dev_name,
+					req->out_map_entries[i].resource_handle,
+					&(req->out_map_entries[i].image_buf_addr),
+					req->out_map_entries[i].sync_id);
+				hdr->word_size = sizeof(uint64_t);
+				addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
+				start = addr;
+				*addr++ = req->request_id;
+				hdr->size = hdr->word_size * (addr - start);
+				dump_args->offset += hdr->size +
+					sizeof(struct cam_context_dump_header);
+			}
+		}
+	}
+
+	/* Dump pending requests */
+	if (!list_empty(&ctx->pending_req_list)) {
+		list_for_each_entry_safe(req, req_temp, &ctx->pending_req_list, list) {
+			for (i = 0; i < req->num_out_map_entries; i++) {
+				dst = (uint8_t *)cpu_addr + dump_args->offset;
+				hdr = (struct cam_context_dump_header *)dst;
+				scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
+					"%s_OUT_FENCE_REQUEST_PENDING.%d.%d.%d:",
+					ctx->dev_name,
+					req->out_map_entries[i].resource_handle,
+					&(req->out_map_entries[i].image_buf_addr),
+					req->out_map_entries[i].sync_id);
+				hdr->word_size = sizeof(uint64_t);
+				addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
+				start = addr;
+				*addr++ = req->request_id;
+				hdr->size = hdr->word_size * (addr - start);
+				dump_args->offset += hdr->size +
+					sizeof(struct cam_context_dump_header);
+			}
+		}
+	}
+
 	/* Dump active requests */
 	if (!list_empty(&ctx->active_req_list)) {
 		list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) {