Skip to content

Commit 61b5d00

Browse files
author
Thomas Zimmermann
committed
drm/fbdev-generic: Clean up after failed probing
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 <[email protected]> Reviewed-by: Javier Martinez Canillas <[email protected]> Acked-by: Zack Rusin <[email protected]> Tested-by: Sui Jingfeng <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 8fbc9af commit 61b5d00

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

drivers/gpu/drm/drm_fbdev_generic.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
7777
struct drm_client_buffer *buffer;
7878
struct fb_info *info;
7979
size_t screen_size;
80+
void *screen_buffer;
8081
u32 format;
8182
int ret;
8283

@@ -92,36 +93,51 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper *fb_helper,
9293

9394
fb_helper->buffer = buffer;
9495
fb_helper->fb = buffer->fb;
96+
9597
screen_size = buffer->gem->size;
98+
screen_buffer = vzalloc(screen_size);
99+
if (!screen_buffer) {
100+
ret = -ENOMEM;
101+
goto err_drm_client_framebuffer_delete;
102+
}
96103

97104
info = drm_fb_helper_alloc_info(fb_helper);
98-
if (IS_ERR(info))
99-
return PTR_ERR(info);
105+
if (IS_ERR(info)) {
106+
ret = PTR_ERR(info);
107+
goto err_vfree;
108+
}
109+
110+
drm_fb_helper_fill_info(info, fb_helper, sizes);
100111

101112
info->fbops = &drm_fbdev_fb_ops;
102-
info->screen_size = screen_size;
103-
info->fix.smem_len = screen_size;
104113
info->flags = FBINFO_DEFAULT;
105114

106-
drm_fb_helper_fill_info(info, fb_helper, sizes);
107-
108-
info->screen_buffer = vzalloc(screen_size);
109-
if (!info->screen_buffer)
110-
return -ENOMEM;
115+
/* screen */
111116
info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
112-
117+
info->screen_buffer = screen_buffer;
113118
info->fix.smem_start = page_to_phys(vmalloc_to_page(info->screen_buffer));
119+
info->fix.smem_len = screen_size;
114120

115-
/* Set a default deferred I/O handler */
121+
/* deferred I/O */
116122
fb_helper->fbdefio.delay = HZ / 20;
117123
fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
118124

119125
info->fbdefio = &fb_helper->fbdefio;
120126
ret = fb_deferred_io_init(info);
121127
if (ret)
122-
return ret;
128+
goto err_drm_fb_helper_release_info;
123129

124130
return 0;
131+
132+
err_drm_fb_helper_release_info:
133+
drm_fb_helper_release_info(fb_helper);
134+
err_vfree:
135+
vfree(screen_buffer);
136+
err_drm_client_framebuffer_delete:
137+
fb_helper->fb = NULL;
138+
fb_helper->buffer = NULL;
139+
drm_client_framebuffer_delete(buffer);
140+
return ret;
125141
}
126142

127143
static void drm_fbdev_damage_blit_real(struct drm_fb_helper *fb_helper,

0 commit comments

Comments
 (0)