[v2,6/8] drm/fbdev-generic: Clean up after failed probing

Sui Jingfeng 15330273260 at 189.cn
Wed Mar 22 07:26:00 UTC 2023


Tested-by: Sui Jingfeng <suijingfeng at loongson.cn>

On 2023/3/20 23:07, Thomas Zimmermann wrote:
> Clean up fbdev and client state if the probe function fails. It
> used to leak allocated resources. Also reorder the individual steps
> to simplify cleanup.
>
> v2:
> 	* move screen_size update into separate patches
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>
> Acked-by: Zack Rusin <zackr at vmware.com>
> ---
>   drivers/gpu/drm/drm_fbdev_generic.c | 40 ++++++++++++++++++++---------
>   1 file changed, 28 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_generic.c
> index 73834a3cc6b0..e7eeba0c44b4 100644
> --- a/drivers/gpu/drm/drm_fbdev_generic.c
> +++ b/drivers/gpu/drm/drm_fbdev_generic.c
> @@ -77,6 +77,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
>   	struct drm_client_buffer *buffer;
>   	struct fb_info *info;
>   	size_t screen_size;
> +	void *screen_buffer;
>   	u32 format;
>   	int ret;
>   
> @@ -92,36 +93,51 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
>   
>   	fb_helper->buffer = buffer;
>   	fb_helper->fb = buffer->fb;
> +
>   	screen_size = buffer->gem->size;
> +	screen_buffer = vzalloc(screen_size);
> +	if (!screen_buffer) {
> +		ret = -ENOMEM;
> +		goto err_drm_client_framebuffer_delete;
> +	}
>   
>   	info = drm_fb_helper_alloc_info(fb_helper);
> -	if (IS_ERR(info))
> -		return PTR_ERR(info);
> +	if (IS_ERR(info)) {
> +		ret = PTR_ERR(info);
> +		goto err_vfree;
> +	}
> +
> +	drm_fb_helper_fill_info(info, fb_helper, sizes);
>   
>   	info->fbops = &drm_fbdev_fb_ops;
> -	info->screen_size = screen_size;
> -	info->fix.smem_len = screen_size;
>   	info->flags = FBINFO_DEFAULT;
>   
> -	drm_fb_helper_fill_info(info, fb_helper, sizes);
> -
> -	info->screen_buffer = vzalloc(screen_size);
> -	if (!info->screen_buffer)
> -		return -ENOMEM;
> +	/* screen */
>   	info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
> -
> +	info->screen_buffer = screen_buffer;
>   	info->fix.smem_start = page_to_phys(vmalloc_to_page(info->screen_buffer));
> +	info->fix.smem_len = screen_size;
>   
> -	/* Set a default deferred I/O handler */
> +	/* deferred I/O */
>   	fb_helper->fbdefio.delay = HZ / 20;
>   	fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
>   
>   	info->fbdefio = &fb_helper->fbdefio;
>   	ret = fb_deferred_io_init(info);
>   	if (ret)
> -		return ret;
> +		goto err_drm_fb_helper_release_info;
>   
>   	return 0;
> +
> +err_drm_fb_helper_release_info:
> +	drm_fb_helper_release_info(fb_helper);
> +err_vfree:
> +	vfree(screen_buffer);
> +err_drm_client_framebuffer_delete:
> +	fb_helper->fb = NULL;
> +	fb_helper->buffer = NULL;
> +	drm_client_framebuffer_delete(buffer);
> +	return ret;
>   }
>   
>   static void drm_fbdev_damage_blit_real(struct drm_fb_helper *fb_helper,


More information about the dri-devel mailing list