summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2025-05-01 12:44:44 +0300
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2025-05-05 10:47:28 +0300
commitbceff719ef46078ddbc3f20298b7b79ad0f67889 (patch)
treeb16b9e2b35f1cddbbf957ef72b1e5004a083ba08
parent72ebfff219459b062394fd2ad886b8e59e0195ca (diff)
downloadlinux-bceff719ef46078ddbc3f20298b7b79ad0f67889.tar.xz
media: atomisp: Avoid deadlock with sensor subdevs with state_lock set
When a (sensor) v4l2_subdev has its state_lock member set to non NULL, then all v4l2_subdev_state-s for the sensor share the same lock. atomisp_init_sensor() calls v4l2_subdev_lock_and_get_active_state() and then later on also tries to lock a separate v4l2_subdev_state used for try calls (rather then changing the active state), while still holding the active state lock. Since this try v4l2_subdev_state shares a lock with the active state this results in a deadlock. Skip locking try_sd_state when sensor->state_lock is set to avoid this. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Andy Shevchenko <andy@kernel.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index 03c535bcb229..ac8fefca7922 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -963,10 +963,17 @@ static void atomisp_init_sensor(struct atomisp_input_subdev *input)
sel.which = V4L2_SUBDEV_FORMAT_TRY;
sel.target = V4L2_SEL_TGT_CROP;
sel.r = input->native_rect;
- v4l2_subdev_lock_state(input->try_sd_state);
+
+ /* Don't lock try_sd_state if the lock is shared with the active state */
+ if (!input->sensor->state_lock)
+ v4l2_subdev_lock_state(input->try_sd_state);
+
err = v4l2_subdev_call(input->sensor, pad, set_selection,
input->try_sd_state, &sel);
- v4l2_subdev_unlock_state(input->try_sd_state);
+
+ if (!input->sensor->state_lock)
+ v4l2_subdev_unlock_state(input->try_sd_state);
+
if (err)
goto unlock_act_sd_state;