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 <ben@xxxxxxxxxxxx> --- 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 4f217f3..c5c8753 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2553,7 +2553,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 34bf177..4d47bcb 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 60998fc..1420aeb 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.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx