drm/i915: Pin backing pages whilst exporting through a dmabuf vmap
[pandora-kernel.git] / drivers / gpu / drm / i915 / i915_gem.c
index 4b2ee7c..ea3a5e1 100644 (file)
@@ -1699,6 +1699,9 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 
        BUG_ON(obj->gtt_space);
 
+       if (obj->pages_pin_count)
+               return -EBUSY;
+
        ops->put_pages(obj);
 
        list_del(&obj->gtt_list);
@@ -1837,6 +1840,8 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
        if (obj->sg_table || obj->pages)
                return 0;
 
+       BUG_ON(obj->pages_pin_count);
+
        ret = ops->get_pages(obj);
        if (ret)
                return ret;
@@ -3743,6 +3748,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
                dev_priv->mm.interruptible = was_interruptible;
        }
 
+       obj->pages_pin_count = 0;
        i915_gem_object_put_pages(obj);
        i915_gem_object_free_mmap_offset(obj);
 
@@ -4402,9 +4408,10 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
 
        cnt = 0;
        list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
-               cnt += obj->base.size >> PAGE_SHIFT;
+               if (obj->pages_pin_count == 0)
+                       cnt += obj->base.size >> PAGE_SHIFT;
        list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
-               if (obj->pin_count == 0)
+               if (obj->pin_count == 0 && obj->pages_pin_count == 0)
                        cnt += obj->base.size >> PAGE_SHIFT;
 
        mutex_unlock(&dev->struct_mutex);