Skip to content

Commit 366e39b

Browse files
l1kdanvet
authored andcommitted
drm/i915: Tear down fbdev if initialization fails
Currently if intelfb_create() errors out, it unrefs the bo even though the fb now owns that reference. (Spotted by Ville Syrjälä.) We should unref the fb instead of the bo. However the fb was not necessarily allocated by intelfb_create(), it could be inherited from BIOS (the fb struct was then allocated by dev_priv->display.get_initial_plane_config()) and be in active use by a crtc. In this case we should call drm_framebuffer_remove() instead of _unreference() to also disable the crtc. Daniel Vetter suggested that "fbdev teardown code will take care of it. The correct approach is probably to not unref anything at all". But if fbdev initialization fails, the fbdev isn't torn down and occupies memory even though it's unusable. Therefore clobber it in intel_fbdev_initial_config(). (Currently we ignore a negative return value there.) The idea is that if fbdev initialization fails, the driver behaves as if CONFIG_DRM_FBDEV_EMULATION wasn't set. Should X11 manage to start up without errors, it will at least be able to use the memory that would otherwise be hogged by the unusable fbdev. Also, log errors in intelfb_create(). Don't call async_synchronize_full() in intel_fbdev_fini() when called from intel_fbdev_initial_config() to avoid deadlock. v2: Instead of calling drm_framebuffer_unreference() (if fb was not inherited from BIOS), call intel_fbdev_fini(). v3: Rebase on e00bf69 (drm/i915: Move the fbdev async_schedule() into intel_fbdev.c), call async_synchronize_full() conditionally instead of moving it into i915_driver_unload(). Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Lukas Wunner <lukas@wunner.de> Link: http://patchwork.freedesktop.org/patch/msgid/49ce5f0daead24b7598ec78591731046c333c18d.1447938059.git.lukas@wunner.de Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1 parent 581da2c commit 366e39b

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

drivers/gpu/drm/i915/intel_fbdev.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
227227

228228
info = drm_fb_helper_alloc_fbi(helper);
229229
if (IS_ERR(info)) {
230+
DRM_ERROR("Failed to allocate fb_info\n");
230231
ret = PTR_ERR(info);
231232
goto out_unpin;
232233
}
@@ -253,6 +254,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
253254
ioremap_wc(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
254255
size);
255256
if (!info->screen_base) {
257+
DRM_ERROR("Failed to remap framebuffer into virtual memory\n");
256258
ret = -ENOSPC;
257259
goto out_destroy_fbi;
258260
}
@@ -285,7 +287,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
285287
drm_fb_helper_release_fbi(helper);
286288
out_unpin:
287289
i915_gem_object_ggtt_unpin(obj);
288-
drm_gem_object_unreference(&obj->base);
289290
mutex_unlock(&dev->struct_mutex);
290291
return ret;
291292
}
@@ -713,7 +714,9 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
713714
struct intel_fbdev *ifbdev = dev_priv->fbdev;
714715

715716
/* Due to peculiar init order wrt to hpd handling this is separate. */
716-
drm_fb_helper_initial_config(&ifbdev->helper, ifbdev->preferred_bpp);
717+
if (drm_fb_helper_initial_config(&ifbdev->helper,
718+
ifbdev->preferred_bpp))
719+
intel_fbdev_fini(dev_priv->dev);
717720
}
718721

719722
void intel_fbdev_initial_config_async(struct drm_device *dev)
@@ -729,7 +732,8 @@ void intel_fbdev_fini(struct drm_device *dev)
729732

730733
flush_work(&dev_priv->fbdev_suspend_work);
731734

732-
async_synchronize_full();
735+
if (!current_is_async())
736+
async_synchronize_full();
733737
intel_fbdev_destroy(dev, dev_priv->fbdev);
734738
kfree(dev_priv->fbdev);
735739
dev_priv->fbdev = NULL;

0 commit comments

Comments
 (0)