[PATCH 5/5] post-process-csb
Chris Wilson
chris at chris-wilson.co.uk
Wed Jun 10 08:41:23 UTC 2020
---
drivers/gpu/drm/i915/gt/intel_engine_types.h | 13 +++++++++
drivers/gpu/drm/i915/gt/intel_lrc.c | 28 +++++++++++++++++---
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 073c3769e8cc..31cf60cef5a8 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -208,6 +208,10 @@ struct intel_engine_execlists {
* @active: the currently known context executing on HW
*/
struct i915_request * const *active;
+ /**
+ * @inactive: the current vacancy of completed CS
+ */
+ struct i915_request **inactive;
/**
* @inflight: the set of contexts submitted and acknowleged by HW
*
@@ -225,6 +229,15 @@ struct intel_engine_execlists {
* preemption or idle-to-active event.
*/
struct i915_request *pending[EXECLIST_MAX_PORTS + 1];
+ /**
+ * @post: the set of completed context switches
+ *
+ * Since we may want to stagger the processing of the CS switches
+ * with the next submission, so that the context are notionally
+ * kept in flight across the dequeue, we defer scheduling out of
+ * the completed context switches.
+ */
+ struct i915_request *post[2 * EXECLIST_MAX_PORTS + 1];
/**
* @port_mask: number of execlist ports - 1
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 5f33342c15e2..355b5383d3dc 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -2055,9 +2055,10 @@ static void set_preempt_timeout(struct intel_engine_cs *engine,
active_preempt_timeout(engine, rq));
}
-static inline void clear_ports(struct i915_request **ports, int count)
+static inline struct i915_request **
+clear_ports(struct i915_request **ports, int count)
{
- memset_p((void **)ports, NULL, count);
+ return memset_p((void **)ports, NULL, count);
}
static void execlists_dequeue(struct intel_engine_cs *engine)
@@ -2455,6 +2456,10 @@ cancel_port_requests(struct intel_engine_execlists * const execlists)
{
struct i915_request * const *port;
+ for (port = execlists->post; *port; port++)
+ execlists_schedule_out(*port);
+ clear_ports(execlists->post, ARRAY_SIZE(execlists->post));
+
for (port = execlists->pending; *port; port++)
execlists_schedule_out(*port);
clear_ports(execlists->pending, ARRAY_SIZE(execlists->pending));
@@ -2622,7 +2627,7 @@ static void process_csb(struct intel_engine_cs *engine)
/* cancel old inflight, prepare for switch */
trace_ports(execlists, "preempted", old);
while (*old)
- execlists_schedule_out(*old++);
+ *execlists->inactive++ = *old++;
/* switch pending to inflight */
GEM_BUG_ON(!assert_pending_valid(execlists, "promote"));
@@ -2679,7 +2684,7 @@ static void process_csb(struct intel_engine_cs *engine)
regs[CTX_RING_TAIL]);
}
- execlists_schedule_out(*execlists->active++);
+ *execlists->inactive++ = *execlists->active++;
GEM_BUG_ON(execlists->active - execlists->inflight >
execlists_num_ports(execlists));
@@ -2703,6 +2708,18 @@ static void process_csb(struct intel_engine_cs *engine)
invalidate_csb_entries(&buf[0], &buf[num_entries - 1]);
}
+static void post_process_csb(struct intel_engine_cs *engine)
+{
+ struct intel_engine_execlists * const el = &engine->execlists;
+ struct i915_request **port;
+
+ GEM_BUG_ON(el->post[2 * EXECLIST_MAX_PORTS]);
+
+ for (port = el->post; *port; port++)
+ execlists_schedule_out(*port);
+ el->inactive = clear_ports(el->post, port - el->post);
+}
+
static void __execlists_submission_tasklet(struct intel_engine_cs *const engine)
{
lockdep_assert_held(&engine->active.lock);
@@ -3133,6 +3150,8 @@ static void execlists_submission_tasklet(unsigned long data)
if (unlikely(timeout && preempt_timeout(engine)))
execlists_reset(engine, "preemption time out");
}
+
+ post_process_csb(engine);
}
static void __execlists_kick(struct intel_engine_execlists *execlists)
@@ -4176,6 +4195,7 @@ static void __execlists_reset(struct intel_engine_cs *engine, bool stalled)
mb();
process_csb(engine); /* drain preemption events */
+ post_process_csb(engine);
/* Following the reset, we need to reload the CSB read/write pointers */
reset_csb_pointers(engine);
--
2.20.1
More information about the Intel-gfx-trybot
mailing list