[Intel-gfx] [RFC 26/37] drm/i915/preempt: preemption-related definitions and statistics

John.C.Harrison at Intel.com John.C.Harrison at Intel.com
Mon Nov 23 03:42:01 PST 2015


From: Dave Gordon <david.s.gordon at intel.com>

For: VIZ-2021
Signed-off-by: Dave Gordon <david.s.gordon at intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c   | 18 ++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h       |  1 +
 drivers/gpu/drm/i915/i915_scheduler.h | 40 +++++++++++++++++++++++++++++++++--
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index e9372ac..7137439 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3690,6 +3690,7 @@ static int i915_scheduler_info(struct seq_file *m, void *unused)
 	struct intel_engine_cs *ring;
 	char   str[50 * (I915_NUM_RINGS + 1)], name[50], *ptr;
 	int ret, i, r;
+	uint32_t pa[I915_NUM_RINGS], pd[I915_NUM_RINGS];
 
 	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
 	if (ret)
@@ -3706,17 +3707,32 @@ static int i915_scheduler_info(struct seq_file *m, void *unused)
 		seq_printf(m, "%s\n", str);				\
 	} while (0)
 
+	for_each_ring(ring, dev_priv, r) {
+		pa[r] = intel_read_status_page(ring, I915_PREEMPTIVE_ACTIVE_SEQNO);
+		pd[r] = intel_read_status_page(ring, I915_PREEMPTIVE_DONE_SEQNO);
+	}
+
 	PRINT_VAR("Ring name:",             "s", dev_priv->ring[r].name);
 	PRINT_VAR("  Ring seqno",           "d", ring->get_seqno(ring, false));
+	PRINT_VAR("  Preemption active",    "d", pa[r]);
+	PRINT_VAR("  Preemption done",      "d", pd[r]);
 	seq_putc(m, '\n');
 
 	seq_puts(m, "Batch submissions:\n");
 	PRINT_VAR("  Queued",               "u", stats[r].queued);
 	PRINT_VAR("  Submitted",            "u", stats[r].submitted);
+	PRINT_VAR("  Preempted",            "u", stats[r].preempted);
 	PRINT_VAR("  Completed",            "u", stats[r].completed);
 	PRINT_VAR("  Expired",              "u", stats[r].expired);
 	seq_putc(m, '\n');
 
+	seq_puts(m, "Preemptions:\n");
+	PRINT_VAR("  Preempts queued",      "u", stats[r].preempts_queued);
+	PRINT_VAR("  Preempts submitted",   "u", stats[r].preempts_submitted);
+	PRINT_VAR("  Preempts completed",   "u", stats[r].preempts_completed);
+	PRINT_VAR("  Max preempted",        "u", stats[r].max_preempted);
+	seq_putc(m, '\n');
+
 	seq_puts(m, "Flush counts:\n");
 	PRINT_VAR("  By object",            "u", stats[r].flush_obj);
 	PRINT_VAR("  By request",           "u", stats[r].flush_req);
@@ -3727,6 +3743,8 @@ static int i915_scheduler_info(struct seq_file *m, void *unused)
 	seq_putc(m, '\n');
 
 	seq_puts(m, "Miscellaneous:\n");
+	PRINT_VAR("  Non batch launched",   "u", stats[r].non_batch);
+	PRINT_VAR("  Non batch landed",     "u", stats[r].non_batch_done);
 	PRINT_VAR("  ExecEarly retry",      "u", stats[r].exec_early);
 	PRINT_VAR("  ExecFinal requeue",    "u", stats[r].exec_again);
 	PRINT_VAR("  ExecFinal killed",     "u", stats[r].exec_dead);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 06dff5a..7b5778b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2314,6 +2314,7 @@ struct drm_i915_gem_request {
 	struct pid *pid;
 
 	struct i915_scheduler_queue_entry	*scheduler_qe;
+	uint32_t                        	scheduler_flags;
 
 	/**
 	 * The ELSP only accepts two elements at a time, so we queue
diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h
index 5257f5c..1597a15 100644
--- a/drivers/gpu/drm/i915/i915_scheduler.h
+++ b/drivers/gpu/drm/i915/i915_scheduler.h
@@ -25,6 +25,16 @@
 #ifndef _I915_SCHEDULER_H_
 #define _I915_SCHEDULER_H_
 
+/* Flag bits for drm_i915_gem_request::scheduler_flags */
+enum {
+	/* Request not submitted via scheduler */
+	i915_req_sf_untracked        = (1 << 0),
+	/* Request was originally preemptive */
+	i915_req_sf_was_preempt      = (1 << 1),
+	/* Request is preemptive */
+	i915_req_sf_preempt          = (1 << 2),
+};
+
 enum i915_scheduler_queue_status {
 	/* Limbo: */
 	i915_sqs_none = 0,
@@ -34,6 +44,10 @@ enum i915_scheduler_queue_status {
 	i915_sqs_popped,
 	/* Sent to hardware for processing: */
 	i915_sqs_flying,
+	/* Sent to hardware for high-priority processing: */
+	i915_sqs_overtaking,
+	/* Previously submitted, but not completed */
+	i915_sqs_preempted,
 	/* Finished processing on the hardware: */
 	i915_sqs_complete,
 	/* Killed by watchdog or catastrophic submission failure: */
@@ -45,11 +59,20 @@ char i915_scheduler_queue_status_chr(enum i915_scheduler_queue_status status);
 const char *i915_scheduler_queue_status_str(
 				enum i915_scheduler_queue_status status);
 
-#define I915_SQS_IS_QUEUED(node)	(((node)->status == i915_sqs_queued))
-#define I915_SQS_IS_FLYING(node)	(((node)->status == i915_sqs_flying))
+#define I915_SQS_IS_QUEUED(node)	(((node)->status == i915_sqs_queued) || \
+					 ((node)->status == i915_sqs_preempted))
+#define I915_SQS_IS_FLYING(node)	(((node)->status == i915_sqs_flying) || \
+					 ((node)->status == i915_sqs_overtaking))
 #define I915_SQS_IS_COMPLETE(node)	(((node)->status == i915_sqs_complete) || \
 					 ((node)->status == i915_sqs_dead))
 
+#define I915_SQS_CASE_QUEUED		i915_sqs_queued:		\
+					case i915_sqs_preempted
+#define I915_SQS_CASE_FLYING		i915_sqs_flying:		\
+					case i915_sqs_overtaking
+#define I915_SQS_CASE_COMPLETE		i915_sqs_complete:		\
+					case i915_sqs_dead
+
 struct i915_scheduler_obj_entry {
 	struct drm_i915_gem_object          *obj;
 };
@@ -83,9 +106,15 @@ struct i915_scheduler_stats {
 	/* Batch buffer counts: */
 	uint32_t            queued;
 	uint32_t            submitted;
+	uint32_t            preempted;
 	uint32_t            completed;
 	uint32_t            expired;
 
+	uint32_t            preempts_queued;
+	uint32_t            preempts_submitted;
+	uint32_t            preempts_completed;
+	uint32_t            max_preempted;
+
 	/* Other stuff: */
 	uint32_t            flush_obj;
 	uint32_t            flush_req;
@@ -94,6 +123,8 @@ struct i915_scheduler_stats {
 	uint32_t            flush_bump;
 	uint32_t            flush_submit;
 
+	uint32_t            non_batch;
+	uint32_t            non_batch_done;
 	uint32_t            exec_early;
 	uint32_t            exec_again;
 	uint32_t            exec_dead;
@@ -130,6 +161,10 @@ enum {
 	i915_sf_interrupts_enabled  = (1 << 0),
 	i915_sf_submitting          = (1 << 1),
 
+	/* Preemption-related state */
+	i915_sf_preempting          = (1 << 4),
+	i915_sf_preempted           = (1 << 5),
+
 	/* Dump/debug flags */
 	i915_sf_dump_force          = (1 << 8),
 	i915_sf_dump_details        = (1 << 9),
@@ -147,6 +182,7 @@ const char *i915_scheduler_flag_str(uint32_t flags);
 enum {
 	i915_so_direct_submit       = (1 << 0),
 	i915_so_submit_on_queue     = (1 << 1),
+	i915_so_no_preemption       = (1 << 2),
 };
 
 bool        i915_scheduler_is_enabled(struct drm_device *dev);
-- 
1.9.1



More information about the Intel-gfx mailing list