drm/i915: don't allocate fbcon from stolen memory if it's too big
authorPaulo Zanoni <paulo.r.zanoni@intel.com>
Wed, 23 Sep 2015 15:52:23 +0000 (12:52 -0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 9 Oct 2015 07:31:58 +0000 (09:31 +0200)
Technology has evolved and now we have eDP panels with 3200x1800
resolution. In the meantime, the BIOS guys didn't change the default
32mb for stolen memory. On top of that, we can't assume our users will
be able to increase the default stolen memory size to more than 32mb -
I'm not even sure all BIOSes allow that.

So just the fbcon buffer alone eats 22mb of my stolen memroy, and due
to the BDW/SKL restriction of not using the last 8mb of stolen memory,
all that's left for FBC is 2mb! Since fbcon is not the coolest feature
ever, I think it's better to save our precious stolen resource to FBC
and the other guys.

On the other hand, we really want to use as much stolen memory as
possible, since on some older systems the stolen memory may be a
considerable percentage of the total available memory.

This patch tries to achieve a little balance using a simple heuristic:
if the fbcon wants more than half of the available stolen memory,
don't use stolen memory in order to leave some for FBC and the other
features.

The long term plan should be to implement a way to set priorities for
stolen memory allocation and then evict low priority users when the
high priority ones need the memory. While we still don't have that,
let's try to make FBC usable with the simple solution.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_fbdev.c

index 539c3737e8233b661a05b283ad07914454aac2f5..184ba09842f588ef9fef29ca6633a66dd2802e79 100644 (file)
@@ -2545,6 +2545,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
                              struct intel_initial_plane_config *plane_config)
 {
        struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_i915_gem_object *obj = NULL;
        struct drm_mode_fb_cmd2 mode_cmd = { 0 };
        struct drm_framebuffer *fb = &plane_config->fb->base;
@@ -2557,6 +2558,12 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
        if (plane_config->size == 0)
                return false;
 
+       /* If the FB is too big, just don't use it since fbdev is not very
+        * important and we should probably use that space with FBC or other
+        * features. */
+       if (size_aligned * 2 > dev_priv->gtt.stolen_usable_size)
+               return false;
+
        obj = i915_gem_object_create_stolen_for_preallocated(dev,
                                                             base_aligned,
                                                             base_aligned,
index 65329127f0b9a2eed2ff29178c4fbd2265840aa5..4fd5fdfef6bd000974d3cf82949fc2b45f4907df 100644 (file)
@@ -121,8 +121,9 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
                container_of(helper, struct intel_fbdev, helper);
        struct drm_framebuffer *fb;
        struct drm_device *dev = helper->dev;
+       struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_mode_fb_cmd2 mode_cmd = {};
-       struct drm_i915_gem_object *obj;
+       struct drm_i915_gem_object *obj = NULL;
        int size, ret;
 
        /* we don't do packed 24bpp */
@@ -139,7 +140,12 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
 
        size = mode_cmd.pitches[0] * mode_cmd.height;
        size = PAGE_ALIGN(size);
-       obj = i915_gem_object_create_stolen(dev, size);
+
+       /* If the FB is too big, just don't use it since fbdev is not very
+        * important and we should probably use that space with FBC or other
+        * features. */
+       if (size * 2 < dev_priv->gtt.stolen_usable_size)
+               obj = i915_gem_object_create_stolen(dev, size);
        if (obj == NULL)
                obj = i915_gem_alloc_object(dev, size);
        if (!obj) {