drm/i915: Reclaim GTT space for failed PPGTT
authorBen Widawsky <ben@bwidawsk.net>
Sat, 26 Jan 2013 00:41:04 +0000 (16:41 -0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 31 Jan 2013 10:50:08 +0000 (11:50 +0100)
When the PPGTT init fails, we may as well reuse the space that we were
reserving for the PPGTT PDEs.

This also fixes an extraneous mutex_unlock.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_gem_gtt.c

index f7e0018626bd0dbebbdffed4de076474df14cc29..71f09a8a00f4a6e35a588e45c5222a6f94221eb8 100644 (file)
@@ -567,12 +567,20 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node,
                        *end -= 4096;
        }
 }
-
 void i915_gem_setup_global_gtt(struct drm_device *dev,
                               unsigned long start,
                               unsigned long mappable_end,
                               unsigned long end)
 {
+       /* Let GEM Manage all of the aperture.
+        *
+        * However, leave one page at the end still bound to the scratch page.
+        * There are a number of places where the hardware apparently prefetches
+        * past the end of the object, and we've seen multiple hangs with the
+        * GPU head pointer stuck in a batchbuffer bound at the last page of the
+        * aperture.  One page should be enough to keep any prefetching inside
+        * of the aperture.
+        */
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_mm_node *entry;
        struct drm_i915_gem_object *obj;
@@ -633,12 +641,12 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long gtt_size, mappable_size;
-       int ret;
 
        gtt_size = dev_priv->gtt.total;
        mappable_size = dev_priv->gtt.mappable_end;
 
        if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) {
+               int ret;
                /* PPGTT pdes are stolen from global gtt ptes, so shrink the
                 * aperture accordingly when using aliasing ppgtt. */
                gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE;
@@ -646,23 +654,14 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
                i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
 
                ret = i915_gem_init_aliasing_ppgtt(dev);
-               if (ret) {
-                       mutex_unlock(&dev->struct_mutex);
+               if (!ret)
                        return;
-               }
-       } else {
-               /* Let GEM Manage all of the aperture.
-                *
-                * However, leave one page at the end still bound to the scratch
-                * page.  There are a number of places where the hardware
-                * apparently prefetches past the end of the object, and we've
-                * seen multiple hangs with the GPU head pointer stuck in a
-                * batchbuffer bound at the last page of the aperture.  One page
-                * should be enough to keep any prefetching inside of the
-                * aperture.
-                */
-               i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
+
+               DRM_ERROR("Aliased PPGTT setup failed %d\n", ret);
+               drm_mm_takedown(&dev_priv->mm.gtt_space);
+               gtt_size += I915_PPGTT_PD_ENTRIES*PAGE_SIZE;
        }
+       i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
 }
 
 static int setup_scratch_page(struct drm_device *dev)