summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Gordon <david.s.gordon@intel.com>2015-10-26 17:52:10 +0000
committerJohn Harrison <John.C.Harrison@Intel.com>2016-06-28 17:19:24 +0100
commit1740b23334e0cb5a676994d0de1c79deb9db78c8 (patch)
treeeb1bd704f100293900c71bc3fb677ef7b9f95696
parentdf92877c5e04db860889d53c4f3f307f526e0fe9 (diff)
drm/i915/preempt: add hook to catch 'unexpected' ring submissions
Author: John Harrison <John.C.Harrison@Intel.com> Date: Thu Apr 10 10:41:06 2014 +0100 The scheduler needs to know what each seqno that pops out of the ring is referring to. This change adds a hook into the the 'submit some random work that got forgotten about' clean up code to inform the scheduler that a new seqno has been sent to the ring for some non-batch buffer operation. Reworked for latest scheduler+preemption by Dave Gordon: with the newer implementation, knowing about untracked requests is merely helpful for debugging rather than being mandatory, as we have already taken steps to prevent untracked requests intruding at awkward moments! v2: Removed unnecessary debug spew. For: VIZ-2021 Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c2
-rw-r--r--drivers/gpu/drm/i915/i915_scheduler.c28
-rw-r--r--drivers/gpu/drm/i915/i915_scheduler.h1
4 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 983aafecce7d..2d3c956e382b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2678,6 +2678,10 @@ void __i915_add_request(struct drm_i915_gem_request *request,
WARN_ON(request->seqno != dev_priv->last_seqno);
}
+ /* Notify the scheduler, if it doesn't already track this request */
+ if (!request->scheduler_qe)
+ i915_scheduler_fly_request(request);
+
/* Record the position of the start of the request so that
* should we detect the updated seqno part-way through the
* GPU processing the request, we never over-estimate the
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 89051700aea7..f87e5cb50b27 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1376,6 +1376,8 @@ static void i915_gem_record_rings(struct drm_device *dev,
i915_gem_obj_ggtt_offset(request->ringbuf->obj);
erq->scheduler_state = !sqe ? 'u' :
i915_scheduler_queue_status_chr(sqe->status);
+ if (request->scheduler_flags & I915_REQ_SF_UNTRACKED)
+ erq->scheduler_state = 'U';
}
}
}
diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index 3887bf92fd26..c7fb5ac5cee9 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -281,6 +281,34 @@ static void i915_scheduler_node_fly(struct i915_scheduler_queue_entry *node)
}
}
+/* An untracked request is being launched ... */
+void i915_scheduler_fly_request(struct drm_i915_gem_request *req)
+{
+ struct drm_i915_private *dev_priv = req->i915;
+ struct i915_scheduler *scheduler = dev_priv->scheduler;
+
+ if (!i915.enable_scheduler) {
+ req->scheduler_flags |= I915_REQ_SF_UNTRACKED;
+ return;
+ }
+
+ WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
+ /* This shouldn't happen */
+ WARN_ON(i915_scheduler_is_engine_busy(req->engine));
+
+ /* We don't expect to see nodes that are already tracked */
+ if (!WARN_ON(req->scheduler_qe)) {
+ /*
+ * Untracked node (e.g. context initialisation batch buffer),
+ * must not be inside scheduler submission path.
+ */
+ WARN_ON((scheduler->flags[req->engine->id] & I915_SF_SUBMITTING));
+ scheduler->stats[req->engine->id].non_batch++;
+ req->scheduler_flags |= I915_REQ_SF_UNTRACKED;
+ }
+}
+
static inline uint32_t i915_scheduler_count_flying(struct i915_scheduler *scheduler,
struct intel_engine_cs *engine)
{
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
index 47b260f8b6b7..f5f93f525e69 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -216,6 +216,7 @@ bool i915_scheduler_is_engine_flying(struct intel_engine_cs *engine);
bool i915_scheduler_is_engine_preempting(struct intel_engine_cs *engine);
bool i915_scheduler_is_engine_busy(struct intel_engine_cs *engine);
void i915_scheduler_work_handler(struct work_struct *work);
+void i915_scheduler_fly_request(struct drm_i915_gem_request *req);
int i915_scheduler_flush(struct intel_engine_cs *engine, bool is_locked);
int i915_scheduler_flush_stamp(struct intel_engine_cs *engine,
unsigned long stamp, bool is_locked);