Lots of functions in the core comedi module expect the mutex in `struct comedi_device` to be held, so add calls to `lockdep_assert_held()` to check and document that. An unusual case is the calls to `lockdep_assert_held()` after successful return from `comedi_alloc_board_minor()` which allocates a `struct comedi_device` and returns with its mutex locked. Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx> --- drivers/staging/comedi/comedi_buf.c | 2 ++ drivers/staging/comedi/comedi_fops.c | 32 ++++++++++++++++++++++++++++ drivers/staging/comedi/drivers.c | 7 ++++++ 3 files changed, 41 insertions(+) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index f693c2c0bec3..d2c8cc72a99d 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -211,6 +211,8 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, { struct comedi_async *async = s->async; + lockdep_assert_held(&dev->mutex); + /* Round up new_size to multiple of PAGE_SIZE */ new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 0caae4a5c471..f6d1287c7b83 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -164,6 +164,7 @@ static bool comedi_clear_board_dev(struct comedi_device *dev) unsigned int i = dev->minor; bool cleared = false; + lockdep_assert_held(&dev->mutex); mutex_lock(&comedi_board_minor_table_lock); if (dev == comedi_board_minor_table[i]) { comedi_board_minor_table[i] = NULL; @@ -260,6 +261,7 @@ comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) { struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (minor >= COMEDI_NUM_BOARD_MINORS) { s = comedi_subdevice_from_minor(dev, minor); if (!s || (s->subdev_flags & SDF_CMD_READ)) @@ -273,6 +275,7 @@ comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor) { struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (minor >= COMEDI_NUM_BOARD_MINORS) { s = comedi_subdevice_from_minor(dev, minor); if (!s || (s->subdev_flags & SDF_CMD_WRITE)) @@ -336,6 +339,8 @@ static int resize_async_buffer(struct comedi_device *dev, struct comedi_async *async = s->async; int retval; + lockdep_assert_held(&dev->mutex); + if (new_size > async->max_bufsize) return -EPERM; @@ -726,6 +731,7 @@ static void do_become_nonbusy(struct comedi_device *dev, { struct comedi_async *async = s->async; + lockdep_assert_held(&dev->mutex); comedi_update_subdevice_runflags(s, COMEDI_SRF_RUNNING, 0); if (async) { comedi_buf_reset(s); @@ -745,6 +751,7 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { int ret = 0; + lockdep_assert_held(&dev->mutex); if (comedi_is_subdevice_running(s) && s->cancel) ret = s->cancel(dev, s); @@ -758,6 +765,7 @@ void comedi_device_cancel_all(struct comedi_device *dev) struct comedi_subdevice *s; int i; + lockdep_assert_held(&dev->mutex); if (!dev->attached) return; @@ -773,6 +781,7 @@ static int is_device_busy(struct comedi_device *dev) struct comedi_subdevice *s; int i; + lockdep_assert_held(&dev->mutex); if (!dev->attached) return 0; @@ -805,6 +814,7 @@ static int do_devconfig_ioctl(struct comedi_device *dev, { struct comedi_devconfig it; + lockdep_assert_held(&dev->mutex); if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -860,6 +870,7 @@ static int do_bufconfig_ioctl(struct comedi_device *dev, struct comedi_subdevice *s; int retval = 0; + lockdep_assert_held(&dev->mutex); if (copy_from_user(&bc, arg, sizeof(bc))) return -EFAULT; @@ -920,6 +931,7 @@ static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_subdevice *s; struct comedi_devinfo devinfo; + lockdep_assert_held(&dev->mutex); memset(&devinfo, 0, sizeof(devinfo)); /* fill devinfo structure */ @@ -966,6 +978,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *tmp, *us; struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); tmp = kcalloc(dev->n_subdevices, sizeof(*tmp), GFP_KERNEL); if (!tmp) return -ENOMEM; @@ -1039,6 +1052,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_subdevice *s; struct comedi_chaninfo it; + lockdep_assert_held(&dev->mutex); if (copy_from_user(&it, arg, sizeof(it))) return -EFAULT; @@ -1098,6 +1112,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, int retval = 0; bool become_nonbusy = false; + lockdep_assert_held(&dev->mutex); if (copy_from_user(&bi, arg, sizeof(bi))) return -EFAULT; @@ -1282,6 +1297,7 @@ static int check_insn_device_config_length(struct comedi_insn *insn, */ static int get_valid_routes(struct comedi_device *dev, unsigned int *data) { + lockdep_assert_held(&dev->mutex); data[1] = dev->get_valid_routes(dev, data[1], data + 2); return 0; } @@ -1293,6 +1309,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, int ret = 0; int i; + lockdep_assert_held(&dev->mutex); if (insn->insn & INSN_MASK_SPECIAL) { /* a non-subdevice instruction */ @@ -1513,6 +1530,7 @@ static int do_insnlist_ioctl(struct comedi_device *dev, int i = 0; int ret = 0; + lockdep_assert_held(&dev->mutex); if (copy_from_user(&insnlist, arg, sizeof(insnlist))) return -EFAULT; @@ -1605,6 +1623,7 @@ static int do_insn_ioctl(struct comedi_device *dev, unsigned int n_data = MIN_SAMPLES; int ret = 0; + lockdep_assert_held(&dev->mutex); if (copy_from_user(&insn, arg, sizeof(insn))) return -EFAULT; @@ -1655,6 +1674,7 @@ static int __comedi_get_user_cmd(struct comedi_device *dev, { struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (copy_from_user(cmd, arg, sizeof(*cmd))) { dev_dbg(dev->class_dev, "bad cmd address\n"); return -EFAULT; @@ -1713,6 +1733,7 @@ static int __comedi_get_user_chanlist(struct comedi_device *dev, unsigned int *chanlist; int ret; + lockdep_assert_held(&dev->mutex); cmd->chanlist = NULL; chanlist = memdup_user(user_chanlist, cmd->chanlist_len * sizeof(unsigned int)); @@ -1754,6 +1775,8 @@ static int do_cmd_ioctl(struct comedi_device *dev, unsigned int __user *user_chanlist; int ret; + lockdep_assert_held(&dev->mutex); + /* get the user's cmd and do some simple validation */ ret = __comedi_get_user_cmd(dev, arg, &cmd); if (ret) @@ -1861,6 +1884,8 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, unsigned int __user *user_chanlist; int ret; + lockdep_assert_held(&dev->mutex); + /* get the user's cmd and do some simple validation */ ret = __comedi_get_user_cmd(dev, arg, &cmd); if (ret) @@ -1914,6 +1939,7 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg, unsigned long flags; struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (arg >= dev->n_subdevices) return -EINVAL; s = &dev->subdevices[arg]; @@ -1946,6 +1972,7 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg, { struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (arg >= dev->n_subdevices) return -EINVAL; s = &dev->subdevices[arg]; @@ -1980,6 +2007,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg, { struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (arg >= dev->n_subdevices) return -EINVAL; s = &dev->subdevices[arg]; @@ -2013,6 +2041,7 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg, { struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (arg >= dev->n_subdevices) return -EINVAL; s = &dev->subdevices[arg]; @@ -2048,6 +2077,7 @@ static int do_setrsubd_ioctl(struct comedi_device *dev, unsigned long arg, struct comedi_file *cfp = file->private_data; struct comedi_subdevice *s_old, *s_new; + lockdep_assert_held(&dev->mutex); if (arg >= dev->n_subdevices) return -EINVAL; @@ -2090,6 +2120,7 @@ static int do_setwsubd_ioctl(struct comedi_device *dev, unsigned long arg, struct comedi_file *cfp = file->private_data; struct comedi_subdevice *s_old, *s_new; + lockdep_assert_held(&dev->mutex); if (arg >= dev->n_subdevices) return -EINVAL; @@ -2995,6 +3026,7 @@ static int __init comedi_init(void) goto out_cleanup_board_minors; } /* comedi_alloc_board_minor() locked the mutex */ + lockdep_assert_held(&dev->mutex); mutex_unlock(&dev->mutex); } diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 5a32b8fc000e..f845f95ca765 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -159,6 +159,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev) int i; struct comedi_subdevice *s; + lockdep_assert_held(&dev->mutex); if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; @@ -196,6 +197,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev) void comedi_device_detach(struct comedi_device *dev) { + lockdep_assert_held(&dev->mutex); comedi_device_cancel_all(dev); down_write(&dev->attach_lock); dev->attached = false; @@ -643,6 +645,7 @@ static int __comedi_device_postconfig_async(struct comedi_device *dev, unsigned int buf_size; int ret; + lockdep_assert_held(&dev->mutex); if ((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0) { dev_warn(dev->class_dev, "async subdevices must support SDF_CMD_READ or SDF_CMD_WRITE\n"); @@ -690,6 +693,7 @@ static int __comedi_device_postconfig(struct comedi_device *dev) int ret; int i; + lockdep_assert_held(&dev->mutex); if (!dev->insn_device_config) dev->insn_device_config = insn_device_inval; @@ -747,6 +751,7 @@ static int comedi_device_postconfig(struct comedi_device *dev) { int ret; + lockdep_assert_held(&dev->mutex); ret = __comedi_device_postconfig(dev); if (ret < 0) return ret; @@ -946,6 +951,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_driver *driv; int ret; + lockdep_assert_held(&dev->mutex); if (dev->attached) return -EBUSY; @@ -1053,6 +1059,7 @@ int comedi_auto_config(struct device *hardware_device, return PTR_ERR(dev); } /* Note: comedi_alloc_board_minor() locked dev->mutex. */ + lockdep_assert_held(&dev->mutex); dev->driver = driver; dev->board_name = dev->driver->driver_name; -- 2.20.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel