diff mbox series

[5/7] vim2m: replace devm_kzalloc by kzalloc

Message ID 20190221142148.3412-6-hverkuil-cisco@xs4all.nl (mailing list archive)
State New, archived
Headers show
Series Various core and virtual driver fixes | expand

Commit Message

Hans Verkuil Feb. 21, 2019, 2:21 p.m. UTC
It is not possible to use devm_kzalloc since that memory is
freed immediately when the device instance is unbound.

Various objects like the video device may still be in use
since someone has the device node open, and when that is closed
it expects the memory to be around.

So use kzalloc and release it at the appropriate time.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/platform/vim2m.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

Comments

Laurent Pinchart Feb. 22, 2019, 11:20 a.m. UTC | #1
Hi Hans,

Thank you for the patch.

On Thu, Feb 21, 2019 at 03:21:46PM +0100, Hans Verkuil wrote:
> It is not possible to use devm_kzalloc since that memory is
> freed immediately when the device instance is unbound.
> 
> Various objects like the video device may still be in use
> since someone has the device node open, and when that is closed
> it expects the memory to be around.
> 
> So use kzalloc and release it at the appropriate time.

You're opening a can of worms, we have tons of drivers that use
devm_kzalloc() :-) I however believe this is the right course of action.

> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> ---
>  drivers/media/platform/vim2m.c | 20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
> index a27d3052bb62..bfb3e3eb48d1 100644
> --- a/drivers/media/platform/vim2m.c
> +++ b/drivers/media/platform/vim2m.c
> @@ -1087,6 +1087,16 @@ static int vim2m_release(struct file *file)
>  	return 0;
>  }
>  
> +static void vim2m_device_release(struct video_device *vdev)
> +{
> +	struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd);
> +
> +	dprintk(dev, "Releasing last dev\n");

Do we really need a debug printk here ?

> +	v4l2_device_unregister(&dev->v4l2_dev);
> +	v4l2_m2m_release(dev->m2m_dev);
> +	kfree(dev);
> +}
> +
>  static const struct v4l2_file_operations vim2m_fops = {
>  	.owner		= THIS_MODULE,
>  	.open		= vim2m_open,
> @@ -1102,7 +1112,7 @@ static const struct video_device vim2m_videodev = {
>  	.fops		= &vim2m_fops,
>  	.ioctl_ops	= &vim2m_ioctl_ops,
>  	.minor		= -1,
> -	.release	= video_device_release_empty,
> +	.release	= vim2m_device_release,
>  	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
>  };
>  
> @@ -1123,13 +1133,13 @@ static int vim2m_probe(struct platform_device *pdev)
>  	struct video_device *vfd;
>  	int ret;
>  
> -	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
> +	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
>  	if (!dev)
>  		return -ENOMEM;
>  
>  	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
>  	if (ret)
> -		return ret;
> +		goto unreg_free;
>  
>  	atomic_set(&dev->num_inst, 0);
>  	mutex_init(&dev->dev_mutex);
> @@ -1192,6 +1202,8 @@ static int vim2m_probe(struct platform_device *pdev)
>  	video_unregister_device(&dev->vfd);
>  unreg_v4l2:
>  	v4l2_device_unregister(&dev->v4l2_dev);
> +unreg_free:

I'd call the label error_free, and rename the other ones with an error_
prefix, as you don't register anything here.

With these two small issues fixes,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +	kfree(dev);
>  
>  	return ret;
>  }
> @@ -1207,9 +1219,7 @@ static int vim2m_remove(struct platform_device *pdev)
>  	v4l2_m2m_unregister_media_controller(dev->m2m_dev);
>  	media_device_cleanup(&dev->mdev);
>  #endif
> -	v4l2_m2m_release(dev->m2m_dev);
>  	video_unregister_device(&dev->vfd);
> -	v4l2_device_unregister(&dev->v4l2_dev);
>  
>  	return 0;
>  }
Hans Verkuil Feb. 25, 2019, 11:27 a.m. UTC | #2
On 2/22/19 12:20 PM, Laurent Pinchart wrote:
> Hi Hans,
> 
> Thank you for the patch.
> 
> On Thu, Feb 21, 2019 at 03:21:46PM +0100, Hans Verkuil wrote:
>> It is not possible to use devm_kzalloc since that memory is
>> freed immediately when the device instance is unbound.
>>
>> Various objects like the video device may still be in use
>> since someone has the device node open, and when that is closed
>> it expects the memory to be around.
>>
>> So use kzalloc and release it at the appropriate time.
> 
> You're opening a can of worms, we have tons of drivers that use
> devm_kzalloc() :-) I however believe this is the right course of action.
> 
>> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
>> ---
>>  drivers/media/platform/vim2m.c | 20 +++++++++++++++-----
>>  1 file changed, 15 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
>> index a27d3052bb62..bfb3e3eb48d1 100644
>> --- a/drivers/media/platform/vim2m.c
>> +++ b/drivers/media/platform/vim2m.c
>> @@ -1087,6 +1087,16 @@ static int vim2m_release(struct file *file)
>>  	return 0;
>>  }
>>  
>> +static void vim2m_device_release(struct video_device *vdev)
>> +{
>> +	struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd);
>> +
>> +	dprintk(dev, "Releasing last dev\n");
> 
> Do we really need a debug printk here ?

Oops, that's a left-over debug message. I'll remove it.

> 
>> +	v4l2_device_unregister(&dev->v4l2_dev);
>> +	v4l2_m2m_release(dev->m2m_dev);
>> +	kfree(dev);
>> +}
>> +
>>  static const struct v4l2_file_operations vim2m_fops = {
>>  	.owner		= THIS_MODULE,
>>  	.open		= vim2m_open,
>> @@ -1102,7 +1112,7 @@ static const struct video_device vim2m_videodev = {
>>  	.fops		= &vim2m_fops,
>>  	.ioctl_ops	= &vim2m_ioctl_ops,
>>  	.minor		= -1,
>> -	.release	= video_device_release_empty,
>> +	.release	= vim2m_device_release,
>>  	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
>>  };
>>  
>> @@ -1123,13 +1133,13 @@ static int vim2m_probe(struct platform_device *pdev)
>>  	struct video_device *vfd;
>>  	int ret;
>>  
>> -	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
>> +	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
>>  	if (!dev)
>>  		return -ENOMEM;
>>  
>>  	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
>>  	if (ret)
>> -		return ret;
>> +		goto unreg_free;
>>  
>>  	atomic_set(&dev->num_inst, 0);
>>  	mutex_init(&dev->dev_mutex);
>> @@ -1192,6 +1202,8 @@ static int vim2m_probe(struct platform_device *pdev)
>>  	video_unregister_device(&dev->vfd);
>>  unreg_v4l2:
>>  	v4l2_device_unregister(&dev->v4l2_dev);
>> +unreg_free:
> 
> I'd call the label error_free, and rename the other ones with an error_
> prefix, as you don't register anything here.

OK

> 
> With these two small issues fixes,
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Regards,

	Hans

> 
>> +	kfree(dev);
>>  
>>  	return ret;
>>  }
>> @@ -1207,9 +1219,7 @@ static int vim2m_remove(struct platform_device *pdev)
>>  	v4l2_m2m_unregister_media_controller(dev->m2m_dev);
>>  	media_device_cleanup(&dev->mdev);
>>  #endif
>> -	v4l2_m2m_release(dev->m2m_dev);
>>  	video_unregister_device(&dev->vfd);
>> -	v4l2_device_unregister(&dev->v4l2_dev);
>>  
>>  	return 0;
>>  }
>
diff mbox series

Patch

diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index a27d3052bb62..bfb3e3eb48d1 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -1087,6 +1087,16 @@  static int vim2m_release(struct file *file)
 	return 0;
 }
 
+static void vim2m_device_release(struct video_device *vdev)
+{
+	struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd);
+
+	dprintk(dev, "Releasing last dev\n");
+	v4l2_device_unregister(&dev->v4l2_dev);
+	v4l2_m2m_release(dev->m2m_dev);
+	kfree(dev);
+}
+
 static const struct v4l2_file_operations vim2m_fops = {
 	.owner		= THIS_MODULE,
 	.open		= vim2m_open,
@@ -1102,7 +1112,7 @@  static const struct video_device vim2m_videodev = {
 	.fops		= &vim2m_fops,
 	.ioctl_ops	= &vim2m_ioctl_ops,
 	.minor		= -1,
-	.release	= video_device_release_empty,
+	.release	= vim2m_device_release,
 	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
 };
 
@@ -1123,13 +1133,13 @@  static int vim2m_probe(struct platform_device *pdev)
 	struct video_device *vfd;
 	int ret;
 
-	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return -ENOMEM;
 
 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
 	if (ret)
-		return ret;
+		goto unreg_free;
 
 	atomic_set(&dev->num_inst, 0);
 	mutex_init(&dev->dev_mutex);
@@ -1192,6 +1202,8 @@  static int vim2m_probe(struct platform_device *pdev)
 	video_unregister_device(&dev->vfd);
 unreg_v4l2:
 	v4l2_device_unregister(&dev->v4l2_dev);
+unreg_free:
+	kfree(dev);
 
 	return ret;
 }
@@ -1207,9 +1219,7 @@  static int vim2m_remove(struct platform_device *pdev)
 	v4l2_m2m_unregister_media_controller(dev->m2m_dev);
 	media_device_cleanup(&dev->mdev);
 #endif
-	v4l2_m2m_release(dev->m2m_dev);
 	video_unregister_device(&dev->vfd);
-	v4l2_device_unregister(&dev->v4l2_dev);
 
 	return 0;
 }