Răsfoiți Sursa

msm: camera: common: Return err on flush and log req id

When UMD requests to flush specific request that was submitted
to HW/FW, return error code back to userspace and log the particular
active request id if the device does not flush active request.
Currently devices that do not support flushing a specific active
request are ICP, OPE, and CRE.

Return error if there is no request to flush upon UMD call to
flush specific request.

Print all ICP requests' id from all active streams when encountering
WD or ICP fatal errors.

CRs-Fixed: 3438283
Change-Id: I7921463250c6e5e45ec263ccdce9d60d2b0f1ed3
Signed-off-by: Sokchetra Eung <[email protected]>
Sokchetra Eung 2 ani în urmă
părinte
comite
d525a7300c

+ 31 - 13
drivers/cam_core/cam_context_utils.c

@@ -332,6 +332,7 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data)
 {
 	struct cam_ctx_request *req = data;
 	struct cam_context *ctx = NULL;
+	struct cam_context_utils_flush_args flush_args;
 	struct cam_flush_dev_cmd flush_cmd;
 	struct cam_req_mgr_apply_request apply;
 	int rc;
@@ -365,7 +366,9 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data)
 			CAM_DBG(CAM_CTXT, "fence error: %d on obj %d",
 				status, sync_obj);
 			flush_cmd.req_id = req->request_id;
-			cam_context_flush_req_to_hw(ctx, &flush_cmd);
+			flush_args.cmd = &flush_cmd;
+			flush_args.flush_active_req = false;
+			cam_context_flush_req_to_hw(ctx, &flush_args);
 		}
 
 		mutex_lock(&ctx->sync_mutex);
@@ -970,10 +973,11 @@ end:
 }
 
 int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
-	struct cam_flush_dev_cmd *cmd)
+	struct cam_context_utils_flush_args *args)
 {
 	struct cam_ctx_request *req = NULL;
 	struct cam_hw_flush_args flush_args = {0};
+	struct cam_flush_dev_cmd *cmd = args->cmd;
 	uint32_t i = 0;
 	int32_t sync_id = 0;
 	int rc = 0;
@@ -1018,13 +1022,22 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
 				rc = -ENOMEM;
 				goto end;
 			}
+
 			spin_lock(&ctx->lock);
 			list_for_each_entry(req, &ctx->active_req_list, list) {
 				if (req->request_id != cmd->req_id)
 					continue;
 
-				list_del_init(&req->list);
+				if (!args->flush_active_req) {
+					CAM_ERR(CAM_CTXT,
+						"[%s][%d] : Flushing active request id: %llu is not supported",
+						ctx->dev_name, ctx->ctx_id, req->request_id);
+					rc = -EPERM;
+					spin_unlock(&ctx->lock);
+					goto end;
+				}
 
+				list_del_init(&req->list);
 				flush_args.flush_req_active[
 					flush_args.num_req_active++] =
 					req->req_priv;
@@ -1090,9 +1103,15 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
 							"pending_list");
 			}
 		}
+
+		rc = 0;
+	} else {
+		CAM_ERR(CAM_CTXT,
+			"[%s][%d] : No pending or active request to flush for req id: %llu",
+			ctx->dev_name, ctx->ctx_id, cmd->req_id);
+		rc = -EINVAL;
 	}
 
-	rc = 0;
 	CAM_DBG(CAM_CTXT, "[%s] X: NRT flush req", ctx->dev_name);
 
 end:
@@ -1102,13 +1121,12 @@ end:
 }
 
 int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx,
-	struct cam_flush_dev_cmd *cmd)
+	struct cam_context_utils_flush_args *flush_args)
 {
-
 	int rc = 0;
 
-	if (!ctx || !cmd) {
-		CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
+	if (!ctx || !flush_args) {
+		CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, flush_args);
 		rc = -EINVAL;
 		goto end;
 	}
@@ -1120,15 +1138,15 @@ int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx,
 		goto end;
 	}
 
-	if (cmd->flush_type == CAM_FLUSH_TYPE_ALL) {
-		ctx->last_flush_req = cmd->req_id;
+	if (flush_args->cmd->flush_type == CAM_FLUSH_TYPE_ALL) {
+		ctx->last_flush_req = flush_args->cmd->req_id;
 		rc = cam_context_flush_ctx_to_hw(ctx);
-	} else if (cmd->flush_type == CAM_FLUSH_TYPE_REQ)
-		rc = cam_context_flush_req_to_hw(ctx, cmd);
+	} else if (flush_args->cmd->flush_type == CAM_FLUSH_TYPE_REQ)
+		rc = cam_context_flush_req_to_hw(ctx, flush_args);
 	else {
 		rc = -EINVAL;
 		CAM_ERR(CAM_CORE, "[%s][%d] Invalid flush type %d",
-			ctx->dev_name, ctx->ctx_id, cmd->flush_type);
+			ctx->dev_name, ctx->ctx_id, flush_args->cmd->flush_type);
 	}
 
 end:

+ 15 - 3
drivers/cam_core/cam_context_utils.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_CONTEXT_UTILS_H_
@@ -10,6 +10,18 @@
 #include <linux/types.h>
 #include "cam_smmu_api.h"
 
+/**
+ * struct cam_context_utils_flush_args - arguments for flush context util
+ *
+ * @cmd: flush dev command from userland
+ * @flush_active_req: flag to indicate if the device supports flushing a particular
+ *                    active request or not
+ */
+struct cam_context_utils_flush_args {
+	struct cam_flush_dev_cmd *cmd;
+	bool flush_active_req;
+};
+
 int cam_context_buf_done_from_hw(struct cam_context *ctx,
 	void *done_event_data, uint32_t evt_id);
 int32_t cam_context_release_dev_to_hw(struct cam_context *ctx,
@@ -24,10 +36,10 @@ int32_t cam_context_start_dev_to_hw(struct cam_context *ctx,
 	struct cam_start_stop_dev_cmd *cmd);
 int32_t cam_context_stop_dev_to_hw(struct cam_context *ctx);
 int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx,
-	struct cam_flush_dev_cmd *cmd);
+	struct cam_context_utils_flush_args *args);
 int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx);
 int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
-	struct cam_flush_dev_cmd *cmd);
+	struct cam_context_utils_flush_args *args);
 int32_t cam_context_send_pf_evt(struct cam_context *ctx,
 	struct cam_hw_dump_pf_args *pf_args);
 int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,

+ 6 - 2
drivers/cam_cre/cam_cre_context.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/debugfs.h>
@@ -38,8 +38,12 @@ static int __cam_cre_ctx_flush_dev_in_ready(struct cam_context *ctx,
 	struct cam_flush_dev_cmd *cmd)
 {
 	int rc;
+	struct cam_context_utils_flush_args flush_args;
 
-	rc = cam_context_flush_dev_to_hw(ctx, cmd);
+	flush_args.cmd = cmd;
+	flush_args.flush_active_req = false;
+
+	rc = cam_context_flush_dev_to_hw(ctx, cmd, &flush_args);
 	if (rc)
 		CAM_ERR(CAM_CRE, "Failed to flush device");
 

+ 6 - 1
drivers/cam_fd/cam_fd_context.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -134,8 +135,12 @@ static int __cam_fd_ctx_flush_dev_in_activated(struct cam_context *ctx,
 	struct cam_flush_dev_cmd *cmd)
 {
 	int rc;
+	struct cam_context_utils_flush_args flush_args;
 
-	rc = cam_context_flush_dev_to_hw(ctx, cmd);
+	flush_args.cmd = cmd;
+	flush_args.flush_active_req = true;
+
+	rc = cam_context_flush_dev_to_hw(ctx, &flush_args);
 	if (rc)
 		CAM_ERR(CAM_ICP, "Failed to flush device, rc=%d", rc);
 

+ 5 - 1
drivers/cam_icp/cam_icp_context.c

@@ -150,8 +150,12 @@ static int __cam_icp_flush_dev_in_ready(struct cam_context *ctx,
 	struct cam_flush_dev_cmd *cmd)
 {
 	int rc;
+	struct cam_context_utils_flush_args flush_args;
 
-	rc = cam_context_flush_dev_to_hw(ctx, cmd);
+	flush_args.cmd = cmd;
+	flush_args.flush_active_req = false;
+
+	rc = cam_context_flush_dev_to_hw(ctx, &flush_args);
 	if (rc)
 		CAM_ERR(CAM_ICP, "[%s] ctx[%u]: Failed to flush device",
 			ctx->dev_name, ctx->ctx_id);

+ 5 - 2
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -2976,6 +2976,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr)
 	CAM_WARN(CAM_ICP, "[%s] hw_mgr[%u] SFR:%s", hw_mgr->hw_mgr_name,
 		hw_mgr->hw_mgr_id, sfr_buffer->msg);
 	cam_icp_dump_debug_info(hw_mgr, false);
+	cam_icp_mgr_dump_active_req_info(hw_mgr);
 
 	cam_icp_mgr_dev_get_gdsc_control(hw_mgr);
 	cam_icp_dev_reset(hw_mgr);
@@ -6521,8 +6522,10 @@ static int cam_icp_mgr_hw_flush(void *hw_priv, void *hw_flush_args)
 	case CAM_FLUSH_TYPE_REQ:
 		mutex_lock(&ctx_data->ctx_mutex);
 		if (flush_args->num_req_active) {
-			CAM_ERR(CAM_ICP, "%s: Flush a specific active request is not supported",
-				ctx_data->ctx_id_string);
+			CAM_ERR(CAM_ICP,
+				"%s: Flush a specific active request id: %lld is not supported",
+				ctx_data->ctx_id_string,
+				*(int64_t *)flush_args->flush_req_active[0]);
 			mutex_unlock(&ctx_data->ctx_mutex);
 			return -EINVAL;
 		}

+ 6 - 2
drivers/cam_jpeg/cam_jpeg_context.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/debugfs.h>
@@ -124,8 +124,12 @@ static int __cam_jpeg_ctx_flush_dev_in_acquired(struct cam_context *ctx,
 	struct cam_flush_dev_cmd *cmd)
 {
 	int rc;
+	struct cam_context_utils_flush_args flush_args;
 
-	rc = cam_context_flush_dev_to_hw(ctx, cmd);
+	flush_args.cmd = cmd;
+	flush_args.flush_active_req = true;
+
+	rc = cam_context_flush_dev_to_hw(ctx, &flush_args);
 	if (rc)
 		CAM_ERR(CAM_ICP, "Failed to flush device");
 

+ 6 - 1
drivers/cam_lrme/cam_lrme_context.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -105,10 +106,14 @@ static int __cam_lrme_ctx_flush_dev_in_activated(struct cam_context *ctx,
 	struct cam_flush_dev_cmd *cmd)
 {
 	int rc;
+	struct cam_context_utils_flush_args flush_args;
 
 	CAM_DBG(CAM_LRME, "Enter ctx %d", ctx->ctx_id);
 
-	rc = cam_context_flush_dev_to_hw(ctx, cmd);
+	flush_args.cmd = cmd;
+	flush_args.flush_active_req = true;
+
+	rc = cam_context_flush_dev_to_hw(ctx, &flush_args);
 	if (rc)
 		CAM_ERR(CAM_LRME, "Failed to flush device");
 

+ 6 - 2
drivers/cam_ope/cam_ope_context.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/debugfs.h>
@@ -109,8 +109,12 @@ static int __cam_ope_flush_dev_in_ready(struct cam_context *ctx,
 	struct cam_flush_dev_cmd *cmd)
 {
 	int rc;
+	struct cam_context_utils_flush_args flush_args;
 
-	rc = cam_context_flush_dev_to_hw(ctx, cmd);
+	flush_args.cmd = cmd;
+	flush_args.flush_active_req = false;
+
+	rc = cam_context_flush_dev_to_hw(ctx, &flush_args);
 	if (rc)
 		CAM_ERR(CAM_OPE, "Failed to flush device");