Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 Sep 2013 02:51:49 +0000 (19:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 Sep 2013 02:51:49 +0000 (19:51 -0700)
Pull drm fixes from Dave Airlie:
 - some small fixes for msm and exynos
 - a regression revert affecting nouveau users with old userspace
 - intel pageflip deadlock and gpu hang fixes, hsw modesetting hangs

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (22 commits)
  Revert "drm: mark context support as a legacy subsystem"
  drm/i915: Don't enable the cursor on a disable pipe
  drm/i915: do not update cursor in crtc mode set
  drm/exynos: fix return value check in lowlevel_buffer_allocate()
  drm/exynos: Fix address space warnings in exynos_drm_fbdev.c
  drm/exynos: Fix address space warning in exynos_drm_buf.c
  drm/exynos: Remove redundant OF dependency
  drm/msm: drop unnecessary set_need_resched()
  drm/i915: kill set_need_resched
  drm/msm: fix potential NULL pointer dereference
  drm/i915/dvo: set crtc timings again for panel fixed modes
  drm/i915/sdvo: Robustify the dtd<->drm_mode conversions
  drm/msm: workaround for missing irq
  drm/msm: return -EBUSY if bo still active
  drm/msm: fix return value check in ERR_PTR()
  drm/msm: fix cmdstream size check
  drm/msm: hangcheck harder
  drm/msm: handle read vs write fences
  drm/i915/sdvo: Fully translate sync flags in the dtd->mode conversion
  drm/i915: Use proper print format for debug prints
  ...

1  2 
drivers/gpu/drm/i915/i915_gem.c

index 8507c6d1e642d872c48f41834a5dbeca53d99c6b,f2a546ef68707bae43326d47eff77479c1a7c23d..df9253d890ee1fbb60482066312a46e7701bf2d4
@@@ -57,12 -57,10 +57,12 @@@ static void i915_gem_object_update_fenc
                                         struct drm_i915_fence_reg *fence,
                                         bool enable);
  
 -static int i915_gem_inactive_shrink(struct shrinker *shrinker,
 -                                  struct shrink_control *sc);
 +static unsigned long i915_gem_inactive_count(struct shrinker *shrinker,
 +                                           struct shrink_control *sc);
 +static unsigned long i915_gem_inactive_scan(struct shrinker *shrinker,
 +                                          struct shrink_control *sc);
  static long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
 -static void i915_gem_shrink_all(struct drm_i915_private *dev_priv);
 +static long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
  static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
  
  static bool cpu_cache_is_coherent(struct drm_device *dev,
                if (i915_terminally_wedged(&dev_priv->gpu_error))
                        return VM_FAULT_SIGBUS;
        case -EAGAIN:
-               /* Give the error handler a chance to run and move the
-                * objects off the GPU active list. Next time we service the
-                * fault, we should be able to transition the page into the
-                * GTT without touching the GPU (and so avoid further
-                * EIO/EGAIN). If the GPU is wedged, then there is no issue
-                * with coherency, just lost writes.
+               /*
+                * EAGAIN means the gpu is hung and we'll wait for the error
+                * handler to reset everything when re-faulting in
+                * i915_mutex_lock_interruptible.
                 */
-               set_need_resched();
        case 0:
        case -ERESTARTSYS:
        case -EINTR:
@@@ -1771,21 -1766,16 +1768,21 @@@ i915_gem_purge(struct drm_i915_private 
        return __i915_gem_shrink(dev_priv, target, true);
  }
  
 -static void
 +static long
  i915_gem_shrink_all(struct drm_i915_private *dev_priv)
  {
        struct drm_i915_gem_object *obj, *next;
 +      long freed = 0;
  
        i915_gem_evict_everything(dev_priv->dev);
  
        list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list,
 -                               global_list)
 +                               global_list) {
 +              if (obj->pages_pin_count == 0)
 +                      freed += obj->base.size >> PAGE_SHIFT;
                i915_gem_object_put_pages(obj);
 +      }
 +      return freed;
  }
  
  static int
@@@ -4565,8 -4555,7 +4562,8 @@@ i915_gem_load(struct drm_device *dev
  
        dev_priv->mm.interruptible = true;
  
 -      dev_priv->mm.inactive_shrinker.shrink = i915_gem_inactive_shrink;
 +      dev_priv->mm.inactive_shrinker.scan_objects = i915_gem_inactive_scan;
 +      dev_priv->mm.inactive_shrinker.count_objects = i915_gem_inactive_count;
        dev_priv->mm.inactive_shrinker.seeks = DEFAULT_SEEKS;
        register_shrinker(&dev_priv->mm.inactive_shrinker);
  }
@@@ -4789,8 -4778,8 +4786,8 @@@ static bool mutex_is_locked_by(struct m
  #endif
  }
  
 -static int
 -i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
 +static unsigned long
 +i915_gem_inactive_count(struct shrinker *shrinker, struct shrink_control *sc)
  {
        struct drm_i915_private *dev_priv =
                container_of(shrinker,
                             mm.inactive_shrinker);
        struct drm_device *dev = dev_priv->dev;
        struct drm_i915_gem_object *obj;
 -      int nr_to_scan = sc->nr_to_scan;
        bool unlock = true;
 -      int cnt;
 +      unsigned long count;
  
        if (!mutex_trylock(&dev->struct_mutex)) {
                if (!mutex_is_locked_by(&dev->struct_mutex, current))
 -                      return 0;
 +                      return SHRINK_STOP;
  
                if (dev_priv->mm.shrinker_no_lock_stealing)
 -                      return 0;
 +                      return SHRINK_STOP;
  
                unlock = false;
        }
  
 -      if (nr_to_scan) {
 -              nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
 -              if (nr_to_scan > 0)
 -                      nr_to_scan -= __i915_gem_shrink(dev_priv, nr_to_scan,
 -                                                      false);
 -              if (nr_to_scan > 0)
 -                      i915_gem_shrink_all(dev_priv);
 -      }
 -
 -      cnt = 0;
 +      count = 0;
        list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list)
                if (obj->pages_pin_count == 0)
 -                      cnt += obj->base.size >> PAGE_SHIFT;
 +                      count += obj->base.size >> PAGE_SHIFT;
  
        list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
                if (obj->active)
                        continue;
  
                if (obj->pin_count == 0 && obj->pages_pin_count == 0)
 -                      cnt += obj->base.size >> PAGE_SHIFT;
 +                      count += obj->base.size >> PAGE_SHIFT;
        }
  
        if (unlock)
                mutex_unlock(&dev->struct_mutex);
 -      return cnt;
 +      return count;
  }
  
  /* All the new VM stuff */
@@@ -4890,40 -4889,6 +4887,40 @@@ unsigned long i915_gem_obj_size(struct 
        return 0;
  }
  
 +static unsigned long
 +i915_gem_inactive_scan(struct shrinker *shrinker, struct shrink_control *sc)
 +{
 +      struct drm_i915_private *dev_priv =
 +              container_of(shrinker,
 +                           struct drm_i915_private,
 +                           mm.inactive_shrinker);
 +      struct drm_device *dev = dev_priv->dev;
 +      int nr_to_scan = sc->nr_to_scan;
 +      unsigned long freed;
 +      bool unlock = true;
 +
 +      if (!mutex_trylock(&dev->struct_mutex)) {
 +              if (!mutex_is_locked_by(&dev->struct_mutex, current))
 +                      return 0;
 +
 +              if (dev_priv->mm.shrinker_no_lock_stealing)
 +                      return 0;
 +
 +              unlock = false;
 +      }
 +
 +      freed = i915_gem_purge(dev_priv, nr_to_scan);
 +      if (freed < nr_to_scan)
 +              freed += __i915_gem_shrink(dev_priv, nr_to_scan,
 +                                                      false);
 +      if (freed < nr_to_scan)
 +              freed += i915_gem_shrink_all(dev_priv);
 +
 +      if (unlock)
 +              mutex_unlock(&dev->struct_mutex);
 +      return freed;
 +}
 +
  struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
                                     struct i915_address_space *vm)
  {