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>
This commit is contained in:
Hans de Goede 2025-05-01 11:44:44 +02:00 committed by Mauro Carvalho Chehab
parent 72ebfff219
commit bceff719ef

View File

@ -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;