diff mbox

[v6,28/34] drm/i915: Add scheduler support functions for TDR

Message ID 1461172435-4256-29-git-send-email-John.C.Harrison@Intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

John Harrison April 20, 2016, 5:13 p.m. UTC
From: John Harrison <John.C.Harrison@Intel.com>

The TDR code needs to know what the scheduler is up to in order to
work out whether a ring is really hung or not.

v4: Removed some unnecessary braces to keep the style checker happy.

v5: Removed white space and added documentation. [Joonas Lahtinen]

Also updated for new module parameter.

v6: Updated to newer nightly (lots of ring -> engine renaming).

Added 'for_each_scheduler_node()' helper macro. Updated to use
'to_i915()' instead of dev_private. [review feedback from Joonas
Lahtinen]

For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_scheduler.c | 33 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_scheduler.h |  1 +
 2 files changed, 34 insertions(+)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
index 74b33f9..e7377bb 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.c
+++ b/drivers/gpu/drm/i915/i915_scheduler.c
@@ -1388,3 +1388,36 @@  void i915_scheduler_closefile(struct drm_device *dev, struct drm_file *file)
 
 	spin_unlock_irq(&scheduler->lock);
 }
+
+/**
+ * i915_scheduler_is_engine_flying - does the given engine have in flight batches?
+ * @engine: Engine to query
+ * Used by TDR to distinguish hung engines (not moving but with work to do)
+ * from idle engines (not moving because there is nothing to do). Returns true
+ * if the given engine has batches currently executing on the hardware.
+ */
+bool i915_scheduler_is_engine_flying(struct intel_engine_cs *engine)
+{
+	struct drm_i915_private *dev_priv = to_i915(engine->dev);
+	struct i915_scheduler *scheduler = dev_priv->scheduler;
+	struct i915_scheduler_queue_entry *node;
+	unsigned long flags;
+	bool found = false;
+
+	/* With the scheduler in bypass mode, no information can be returned. */
+	if (!i915.enable_scheduler)
+		return true;
+
+	spin_lock_irqsave(&scheduler->lock, flags);
+
+	for_each_scheduler_node(node, engine->id) {
+		if (I915_SQS_IS_FLYING(node)) {
+			found = true;
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&scheduler->lock, flags);
+
+	return found;
+}
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
index 75d7962..bdb9403 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -145,6 +145,7 @@  void i915_scheduler_clean_node(struct i915_scheduler_queue_entry *node);
 int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe);
 bool i915_scheduler_notify_request(struct drm_i915_gem_request *req);
 void i915_scheduler_wakeup(struct drm_device *dev);
+bool i915_scheduler_is_engine_flying(struct intel_engine_cs *engine);
 void i915_scheduler_work_handler(struct work_struct *work);
 int i915_scheduler_flush(struct intel_engine_cs *engine, bool is_locked);
 int i915_scheduler_flush_stamp(struct intel_engine_cs *engine,