Browse Source

video: driver: fix race issue with core_init sequence

New session open followed by system_error will attempt to
core_init again, at the same time client is attempting to
open 2nd session, so core->state is moved to init_wait
atate.

1st session core_init request is getting timedout and i.e
leading to force core_deinit and core->state also moved to
core_deinit state.

At the sametime client is attempting to open 3rd session,
and unfortunately core is in deinit state, so it bypasses
all init_wait check moved ahead and attempted core_init
again and moved core state to init_wait and waits for
core_init_done with timeout.

2nd session got timedout and attempts deinit and moved
&core->state to core_deinit.

Client again attempts 4th session open and that will attempt
to reinitialize &core->init_done completion struct, on which
3rd session is already waiting for. So that is leading to
list corruption failure at core kernel side.

Change-Id: Idaf96355c18f34e4204214b18479f067cfc47165
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 3 years ago
parent
commit
830f916172
2 changed files with 3 additions and 3 deletions
  1. 1 2
      driver/vidc/src/msm_vidc_driver.c
  2. 2 1
      driver/vidc/src/msm_vidc_probe.c

+ 1 - 2
driver/vidc/src/msm_vidc_driver.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2020-2022, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/iommu.h>
@@ -4500,7 +4500,6 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
 		goto unlock;
 
 	msm_vidc_change_core_state(core, MSM_VIDC_CORE_INIT_WAIT, __func__);
-	init_completion(&core->init_done);
 	core->smmu_fault_handled = false;
 	core->ssr.trigger = false;
 	core->pm_suspended = false;

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

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2020-2022, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/workqueue.h>
@@ -291,6 +291,7 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
 	}
 
 	mutex_init(&core->lock);
+	init_completion(&core->init_done);
 	INIT_LIST_HEAD(&core->instances);
 	INIT_LIST_HEAD(&core->dangling_instances);