Re: [PATCH] iio: fix kobject_put warning in iio_device_register

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

 



On Thu, 10 Nov 2022 21:26:15 +0800
Zeng Heng <zengheng4@xxxxxxxxxx> wrote:

> There is warning reported by kobject lib in kobject_put():
> 
> kobject: '(null)' (00000000be81a546): is not initialized, yet kobject_put() is being called.
> WARNING: CPU: 0 PID: 535 at lib/kobject.c:718 kobject_put+0x12c/0x180
> Call Trace:
>  cdev_device_add
>  __iio_device_register
>  __devm_iio_device_register
>  tmp117_probe
> 
> If don't need to register chardev for most of IIO devices,
> we just register them with device_add() only, and use device_del()
> to unregister them.



> 
> Otherwise, when device_add() fails in internal and calls kobject_put()
> in error handling path, it would report warning because the device
> never be registered as chardev and there is no release function for it.
> 
> Fixes: 8ebaa3ff1e71 ("iio: core: register chardev only if needed")
> Signed-off-by: Zeng Heng <zengheng4@xxxxxxxxxx>

Interesting corner case. The cdev_device_add() call is fine with
!dev->devt which is what this code was taking advantage of. The exception
as you have highlighted is the error path of device_add().

So I think it should also cope with unwinding if device_add() fails
and not be calling cdev_del()  Note that cdev_device_del() has the
appropriate guards to be safe whether or not (dev->devt) is true.

Perhaps change cdev_device_add() to have

	rc = device_add(dev);
	if (rc && dev->devt)
		cdev_del(cdev);

	return rc;

Jonathan

> ---
>  drivers/iio/industrialio-core.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 151ff3993354..f4f48bda07f7 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -1982,7 +1982,11 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
>  	/* assign device groups now; they should be all registered now */
>  	indio_dev->dev.groups = iio_dev_opaque->groups;
>  
> -	ret = cdev_device_add(&iio_dev_opaque->chrdev, &indio_dev->dev);
> +	if (iio_dev_opaque->attached_buffers_cnt || iio_dev_opaque->event_interface)
> +		ret = cdev_device_add(&iio_dev_opaque->chrdev, &indio_dev->dev);
> +	else
> +		ret = device_add(&indio_dev->dev);
> +
>  	if (ret < 0)
>  		goto error_unreg_eventset;
>  
> @@ -2008,7 +2012,10 @@ void iio_device_unregister(struct iio_dev *indio_dev)
>  {
>  	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
>  
> -	cdev_device_del(&iio_dev_opaque->chrdev, &indio_dev->dev);
> +	if (iio_dev_opaque->chrdev.kobj.state_initialized)
> +		cdev_device_del(&iio_dev_opaque->chrdev, &indio_dev->dev);
> +	else
> +		device_del(&indio_dev->dev);
>  
>  	mutex_lock(&iio_dev_opaque->info_exist_lock);
>  




[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