Re: [PATCH v2] iio: Use per-device lockdep class for mlock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Aug 29, 2022 at 12:18 PM Vincent Whitchurch
<vincent.whitchurch@xxxxxxxx> wrote:
>
> If an IIO driver uses callbacks from another IIO driver and calls
> iio_channel_start_all_cb() from one of its buffer setup ops, then
> lockdep complains due to the lock nesting, as in the below example with
> lmp91000.
>
> Since the locks are being taken on different IIO devices, there is no
> actual deadlock.  Fix the warning by telling lockdep to use a different
> class for each iio_device.
>
>  ============================================
>  WARNING: possible recursive locking detected
>  --------------------------------------------
>  python3/23 is trying to acquire lock:
>  (&indio_dev->mlock){+.+.}-{3:3}, at: iio_update_buffers
>
>  but task is already holding lock:
>  (&indio_dev->mlock){+.+.}-{3:3}, at: enable_store
>
>  other info that might help us debug this:
>   Possible unsafe locking scenario:
>
>         CPU0
>         ----
>    lock(&indio_dev->mlock);
>    lock(&indio_dev->mlock);
>
>   *** DEADLOCK ***
>
>   May be due to missing lock nesting notation
>
>  5 locks held by python3/23:
>   #0: (sb_writers#5){.+.+}-{0:0}, at: ksys_write
>   #1: (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter
>   #2: (kn->active#14){.+.+}-{0:0}, at: kernfs_fop_write_iter
>   #3: (&indio_dev->mlock){+.+.}-{3:3}, at: enable_store
>   #4: (&iio_dev_opaque->info_exist_lock){+.+.}-{3:3}, at: iio_update_buffers
>
>  Call Trace:
>   __mutex_lock
>   iio_update_buffers
>   iio_channel_start_all_cb
>   lmp91000_buffer_postenable
>   __iio_update_buffers
>   enable_store


This looks much better than the previous version, thanks!
Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>

> Fixes: 67e17300dc1d76 ("iio: potentiostat: add LMP91000 support")
> Signed-off-by: Vincent Whitchurch <vincent.whitchurch@xxxxxxxx>
> ---
>
> Notes:
>     v2:
>     - Use a different lockdep class for each iio_device, instead of using
>       mutex_lock_nested.
>     - Add fixes tag pointing to first IIO driver which used this API.
>     - Trim call stack in commit message.
>
>  drivers/iio/industrialio-core.c | 5 +++++
>  include/linux/iio/iio-opaque.h  | 2 ++
>  2 files changed, 7 insertions(+)
>
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 0f4dbda3b9d3..921d8e8643a2 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -1621,6 +1621,8 @@ static void iio_dev_release(struct device *device)
>
>         iio_device_detach_buffers(indio_dev);
>
> +       lockdep_unregister_key(&iio_dev_opaque->mlock_key);
> +
>         ida_free(&iio_ida, iio_dev_opaque->id);
>         kfree(iio_dev_opaque);
>  }
> @@ -1680,6 +1682,9 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
>         INIT_LIST_HEAD(&iio_dev_opaque->buffer_list);
>         INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
>
> +       lockdep_register_key(&iio_dev_opaque->mlock_key);
> +       lockdep_set_class(&indio_dev->mlock, &iio_dev_opaque->mlock_key);
> +
>         return indio_dev;
>  }
>  EXPORT_SYMBOL(iio_device_alloc);
> diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h
> index 6b3586b3f952..d1f8b30a7c8b 100644
> --- a/include/linux/iio/iio-opaque.h
> +++ b/include/linux/iio/iio-opaque.h
> @@ -11,6 +11,7 @@
>   *                             checked by device drivers but should be considered
>   *                             read-only as this is a core internal bit
>   * @driver_module:             used to make it harder to undercut users
> + * @mlock_key:                 lockdep class for iio_dev lock
>   * @info_exist_lock:           lock to prevent use during removal
>   * @trig_readonly:             mark the current trigger immutable
>   * @event_interface:           event chrdevs associated with interrupt lines
> @@ -42,6 +43,7 @@ struct iio_dev_opaque {
>         int                             currentmode;
>         int                             id;
>         struct module                   *driver_module;
> +       struct lock_class_key           mlock_key;
>         struct mutex                    info_exist_lock;
>         bool                            trig_readonly;
>         struct iio_event_interface      *event_interface;
> --
> 2.34.1
>


-- 
With Best Regards,
Andy Shevchenko



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux