There are no users of this yet, but the idea is presented and split out
to find bugs.

Also, while here, return -ERESTARTSYS to the caller, in case they want
to do something with it.

Signed-off-by: Ben Widawsky <b...@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_drv.h            |  2 +-
 drivers/gpu/drm/i915/i915_gem_context.c    |  5 ++---
 drivers/gpu/drm/i915/i915_gem_evict.c      | 32 ++++++++++++++++++++++--------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  2 +-
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d3a69aa..6c252c3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2478,7 +2478,7 @@ int __must_check i915_gem_evict_something(struct 
drm_device *dev,
                                          unsigned long start,
                                          unsigned long end,
                                          unsigned flags);
-int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
+int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle, bool 
interruptible);
 int i915_gem_evict_everything(struct drm_device *dev);
 
 /* belongs in i915_gem_gtt.h */
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index cf7cf81..b6803b3 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -121,11 +121,10 @@ static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
                        if (WARN_ON(list_empty(&vma->vma_link) ||
                                    list_is_singular(&vma->vma_link)))
                                break;
-
-               i915_gem_evict_vm(&ppgtt->base, true);
+               i915_gem_evict_vm(&ppgtt->base, true, true);
        } else {
                i915_gem_retire_requests(dev);
-               i915_gem_evict_vm(&ppgtt->base, false);
+               i915_gem_evict_vm(&ppgtt->base, false, true);
        }
 
        ppgtt->base.cleanup(&ppgtt->base);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 38297d3..ac8d90f 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -197,8 +197,9 @@ found:
 /**
  * i915_gem_evict_vm - Evict all idle vmas from a vm
  *
- * @vm: Address space to cleanse
- * @do_idle: Boolean directing whether to idle first.
+ * @vm:                        Address space to cleanse
+ * @do_idle:           Boolean directing whether to idle first.
+ * @interruptible:     How to wait
  *
  * This function evicts all idles vmas from a vm. If all unpinned vmas should 
be
  * evicted the @do_idle needs to be set to true.
@@ -209,18 +210,24 @@ found:
  * To clarify: This is for freeing up virtual address space, not for freeing
  * memory in e.g. the shrinker.
  */
-int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
+int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle, bool 
interruptible)
 {
+       struct drm_i915_private *dev_priv = to_i915(vm->dev);
+
        struct i915_vma *vma, *next;
+       bool was_intr = dev_priv->mm.interruptible;
        int ret;
 
        BUG_ON(!mutex_is_locked(&vm->dev->struct_mutex));
        trace_i915_gem_evict_vm(vm);
 
+       if (!interruptible)
+               dev_priv->mm.interruptible = false;
+
        if (do_idle) {
                ret = i915_gpu_idle(vm->dev);
                if (ret)
-                       return ret;
+                       goto out;
 
                i915_gem_retire_requests(vm->dev);
 
@@ -229,11 +236,20 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool 
do_idle)
 
        list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list) {
                WARN_ON(!i915_is_ggtt(vm) && vma->pin_count);
-               if (vma->pin_count == 0)
-                       WARN_ON(i915_vma_unbind(vma));
+               if (vma->pin_count == 0) {
+                       ret = i915_vma_unbind(vma);
+                       if (ret == -ERESTARTSYS) {
+                               BUG_ON(!interruptible);
+                               goto out;
+                       } else if (ret)
+                               WARN(1, "Failed to unbind vma %d\n", ret);
+               }
        }
+       ret = 0;
 
-       return 0;
+out:
+       dev_priv->mm.interruptible = was_intr;
+       return ret;
 }
 
 /**
@@ -276,7 +292,7 @@ i915_gem_evict_everything(struct drm_device *dev)
 
        /* Having flushed everything, unbind() should never raise an error */
        list_for_each_entry(vm, &dev_priv->vm_list, global_link)
-               WARN_ON(i915_gem_evict_vm(vm, false));
+               WARN_ON(i915_gem_evict_vm(vm, false, true));
 
        return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index d815ef5..40ec61c 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -722,7 +722,7 @@ err:
                list_for_each_entry(vma, vmas, exec_list)
                        i915_gem_execbuffer_unreserve_vma(vma);
 
-               ret = i915_gem_evict_vm(vm, true);
+               ret = i915_gem_evict_vm(vm, true, true);
                if (ret)
                        return ret;
        } while (1);
-- 
2.0.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to