summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem_evict.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-06-24 14:55:57 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2016-06-24 15:03:14 +0100
commit6e5a5beb8e344b1ab929de0c8446a61a70ed94ba (patch)
tree1bfb6d8e8fc086c5b3ee78aa025d93d5cc84dbe9 /drivers/gpu/drm/i915/i915_gem_evict.c
parentec602a0dfb394ac3a5f91d03c4d6fab6e45302cc (diff)
downloadop-kernel-dev-6e5a5beb8e344b1ab929de0c8446a61a70ed94ba.zip
op-kernel-dev-6e5a5beb8e344b1ab929de0c8446a61a70ed94ba.tar.gz
drm/i915: Split idling from forcing context switch
We only need to force a switch to the kernel context placeholder during eviction. All other uses of i915_gpu_idle() just want to wait until existing work on the GPU is idle. Rename i915_gpu_idle() to i915_gem_wait_for_idle() to avoid any implications about "parking" the context first. v2: Tweak an error message if the wait fails for the ilk vtd w/a Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-6-git-send-email-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_evict.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index b144c3f..5741b58 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -33,6 +33,37 @@
#include "intel_drv.h"
#include "i915_trace.h"
+static int switch_to_pinned_context(struct drm_i915_private *dev_priv)
+{
+ struct intel_engine_cs *engine;
+
+ if (i915.enable_execlists)
+ return 0;
+
+ for_each_engine(engine, dev_priv) {
+ struct drm_i915_gem_request *req;
+ int ret;
+
+ if (engine->last_context == NULL)
+ continue;
+
+ if (engine->last_context == dev_priv->kernel_context)
+ continue;
+
+ req = i915_gem_request_alloc(engine, dev_priv->kernel_context);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ ret = i915_switch_context(req);
+ i915_add_request_no_flush(req);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+
static bool
mark_free(struct i915_vma *vma, struct list_head *unwind)
{
@@ -150,11 +181,17 @@ none:
/* Only idle the GPU and repeat the search once */
if (pass++ == 0) {
- ret = i915_gpu_idle(dev);
+ struct drm_i915_private *dev_priv = to_i915(dev);
+
+ ret = switch_to_pinned_context(dev_priv);
if (ret)
return ret;
- i915_gem_retire_requests(to_i915(dev));
+ ret = i915_gem_wait_for_idle(dev_priv);
+ if (ret)
+ return ret;
+
+ i915_gem_retire_requests(dev_priv);
goto search_again;
}
@@ -261,11 +298,17 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
trace_i915_gem_evict_vm(vm);
if (do_idle) {
- ret = i915_gpu_idle(vm->dev);
+ struct drm_i915_private *dev_priv = to_i915(vm->dev);
+
+ ret = switch_to_pinned_context(dev_priv);
+ if (ret)
+ return ret;
+
+ ret = i915_gem_wait_for_idle(dev_priv);
if (ret)
return ret;
- i915_gem_retire_requests(to_i915(vm->dev));
+ i915_gem_retire_requests(dev_priv);
WARN_ON(!list_empty(&vm->active_list));
}
OpenPOWER on IntegriCloud