Browse Source

video: driver: remove smmu_fault_work_handler

Remove separate fault_work_handler and print all needed
debug info as part of smmu_fault_handler callback itself,
to avoid race between fault handler invocation and core
deinit sequence.

Change-Id: Ib47e3d457a5a3e33497c71d5920382cb43baed79
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 4 years ago
parent
commit
1524ddc445

+ 2 - 7
driver/variant/iris2/src/msm_vidc_iris2.c

@@ -387,19 +387,14 @@ static int __noc_error_info_iris2(struct msm_vidc_core *vidc_core)
 		return -EINVAL;
 	}
 
-	/* check ErrLog registers contain valid info */
-	if (!__read_register(core, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW)) {
-		d_vpr_e("%s: VCODEC_NOC_ERL_MAIN_ERRVLD_LOW bit not-set\n", __func__);
-		/* todo: uncomment below line after validation */
-		//return 0;
-	}
-
 	val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_LOW);
 	d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_LOW:     %#x\n", val);
 	val = __read_register(core, VCODEC_NOC_ERL_MAIN_SWID_HIGH);
 	d_vpr_e("VCODEC_NOC_ERL_MAIN_SWID_HIGH:     %#x\n", val);
 	val = __read_register(core, VCODEC_NOC_ERL_MAIN_MAINCTL_LOW);
 	d_vpr_e("VCODEC_NOC_ERL_MAIN_MAINCTL_LOW:     %#x\n", val);
+	val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRVLD_LOW);
+	d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRVLD_LOW:     %#x\n", val);
 	val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRCLR_LOW);
 	d_vpr_e("VCODEC_NOC_ERL_MAIN_ERRCLR_LOW:     %#x\n", val);
 	val = __read_register(core, VCODEC_NOC_ERL_MAIN_ERRLOG0_LOW);

+ 0 - 1
driver/vidc/inc/msm_vidc_core.h

@@ -84,7 +84,6 @@ struct msm_vidc_core {
 	struct msm_vidc_mem_addr               iface_q_table;
 	struct msm_vidc_iface_q_info           iface_queues[VIDC_IFACEQ_NUMQ];
 	struct work_struct                     device_work;
-	struct work_struct                     smmu_fault_work;
 	struct workqueue_struct               *device_workq;
 	struct delayed_work                    pm_work;
 	struct workqueue_struct               *pm_workq;

+ 1 - 1
driver/vidc/inc/msm_vidc_driver.h

@@ -272,7 +272,7 @@ int msm_vidc_core_init(struct msm_vidc_core *core);
 int msm_vidc_core_deinit(struct msm_vidc_core *core, bool force);
 int msm_vidc_core_timeout(struct msm_vidc_core *core);
 int msm_vidc_print_inst_info(struct msm_vidc_inst *inst);
-void msm_vidc_smmu_fault_work_handler(struct work_struct *work);
+void msm_vidc_print_core_info(struct msm_vidc_core *core);
 int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
 		struct device *dev, unsigned long iova, int flags, void *data);
 int msm_vidc_trigger_ssr(struct msm_vidc_core *core,

+ 1 - 1
driver/vidc/inc/venus_hfi.h

@@ -46,7 +46,7 @@ int venus_hfi_session_open(struct msm_vidc_inst *inst);
 int venus_hfi_session_set_codec(struct msm_vidc_inst *inst);
 int venus_hfi_core_init(struct msm_vidc_core *core);
 int venus_hfi_core_deinit(struct msm_vidc_core *core);
-int venus_print_noc_error_info(struct msm_vidc_core *core);
+int venus_hfi_noc_error_info(struct msm_vidc_core *core);
 int venus_hfi_suspend(struct msm_vidc_core *core);
 int venus_hfi_scale_clocks(struct msm_vidc_inst* inst, u64 freq);
 int venus_hfi_scale_buses(struct msm_vidc_inst* inst, u64 bw_ddr, u64 bw_llcc);

+ 6 - 11
driver/vidc/src/msm_vidc_driver.c

@@ -3397,22 +3397,17 @@ int msm_vidc_print_inst_info(struct msm_vidc_inst *inst)
 	return 0;
 }
 
-void msm_vidc_smmu_fault_work_handler(struct work_struct *work)
+void msm_vidc_print_core_info(struct msm_vidc_core *core)
 {
-	struct msm_vidc_core *core;
 	struct msm_vidc_inst *inst = NULL;
 	struct msm_vidc_inst *instances[MAX_SUPPORTED_INSTANCES];
 	s32 num_instances = 0;
 
-	core = container_of(work, struct msm_vidc_core, smmu_fault_work);
 	if (!core) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		return;
 	}
 
-	/* print noc error log registers */
-	venus_print_noc_error_info(core);
-
 	core_lock(core, __func__);
 	list_for_each_entry(inst, &core->instances, list)
 		instances[num_instances++] = inst;
@@ -3453,11 +3448,11 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
 	d_vpr_e("%s: faulting address: %lx\n", __func__, iova);
 
 	core->smmu_fault_handled = true;
-	/**
-	 * Fault handler shouldn't be blocked for longtime. So offload work
-	 * to device_workq to print buffer and memory consumption details.
-	 */
-	queue_work(core->device_workq, &core->smmu_fault_work);
+
+	/* print noc error log registers */
+	venus_hfi_noc_error_info(core);
+
+	msm_vidc_print_core_info(core);
 	/*
 	 * Return -ENOSYS to elicit the default behaviour of smmu driver.
 	 * If we return -ENOSYS, then smmu driver assumes page fault handler

+ 0 - 1
driver/vidc/src/msm_vidc_probe.c

@@ -234,7 +234,6 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
 	INIT_LIST_HEAD(&core->dangling_instances);
 
 	INIT_WORK(&core->device_work, venus_hfi_work_handler);
-	INIT_WORK(&core->smmu_fault_work, msm_vidc_smmu_fault_work_handler);
 	INIT_DELAYED_WORK(&core->pm_work, venus_hfi_pm_work_handler);
 	INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
 	INIT_WORK(&core->ssr_work, msm_vidc_ssr_handler);

+ 5 - 2
driver/vidc/src/venus_hfi.c

@@ -2847,9 +2847,9 @@ int venus_hfi_core_deinit(struct msm_vidc_core *core)
 	return 0;
 }
 
-int venus_print_noc_error_info(struct msm_vidc_core *core)
+int venus_hfi_noc_error_info(struct msm_vidc_core *core)
 {
-	if (!core) {
+	if (!core || !core->capabilities) {
 		d_vpr_e("%s: Invalid parameters: %pK\n",
 			__func__, core);
 		return -EINVAL;
@@ -2859,6 +2859,9 @@ int venus_print_noc_error_info(struct msm_vidc_core *core)
 		return 0;
 
 	core_lock(core, __func__);
+	if (core->state == MSM_VIDC_CORE_DEINIT)
+		goto unlock;
+
 	/* resume venus before accessing noc registers */
 	if (__resume(core)) {
 		d_vpr_e("%s: Power on failed\n", __func__);

+ 1 - 1
driver/vidc/src/venus_hfi_response.c

@@ -315,7 +315,7 @@ int handle_system_error(struct msm_vidc_core *core,
 {
 	d_vpr_e("%s: system error received\n", __func__);
 	print_sfr_message(core);
-	venus_print_noc_error_info(core);
+	venus_hfi_noc_error_info(core);
 	msm_vidc_core_deinit(core, true);
 	return 0;
 }