[PATCH 6/6] lrm-literestore
Chris Wilson
chris at chris-wilson.co.uk
Fri Feb 7 00:21:47 UTC 2020
---
drivers/gpu/drm/i915/gt/intel_engine_cs.c | 13 +++--
drivers/gpu/drm/i915/gt/intel_lrc.c | 71 ++++++++++++++++++++++-
2 files changed, 77 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index b1c7b1ed6149..0aee25abadff 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -662,6 +662,7 @@ static int measure_breadcrumb_dw(struct intel_engine_cs *engine)
frame->rq.i915 = engine->i915;
frame->rq.engine = engine;
frame->rq.ring = &frame->ring;
+ frame->rq.context = engine->kernel_context;
rcu_assign_pointer(frame->rq.timeline, &frame->timeline);
dw = intel_timeline_pin(&frame->timeline);
@@ -754,12 +755,6 @@ static int engine_init_common(struct intel_engine_cs *engine)
engine->set_default_submission(engine);
- ret = measure_breadcrumb_dw(engine);
- if (ret < 0)
- return ret;
-
- engine->emit_fini_breadcrumb_dw = ret;
-
/*
* We may need to do things with the shrinker which
* require us to immediately switch back to the default
@@ -774,6 +769,12 @@ static int engine_init_common(struct intel_engine_cs *engine)
engine->kernel_context = ce;
+ ret = measure_breadcrumb_dw(engine);
+ if (ret < 0)
+ return ret;
+
+ engine->emit_fini_breadcrumb_dw = ret;
+
return 0;
}
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 6fac0f06aba6..d1c61a50f173 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1763,6 +1763,60 @@ static inline void clear_ports(struct i915_request **ports, int count)
memset_p((void **)ports, NULL, count);
}
+static bool skip_lite_restore(struct intel_engine_cs *const engine,
+ struct i915_request *first)
+{
+ struct intel_engine_execlists *const execlists = &engine->execlists;
+ struct i915_request *last = first;
+ struct rb_node *rb;
+ bool submit = false;
+
+ while ((rb = rb_first_cached(&execlists->queue))) {
+ struct i915_priolist *p = to_priolist(rb);
+ struct i915_request *rq, *rn;
+ int i;
+
+ priolist_for_each_request_consume(rq, rn, p, i) {
+ if (!can_merge_rq(last, rq))
+ goto out;
+
+ if (__i915_request_submit(rq)) {
+ submit = true;
+ last = rq;
+ }
+ }
+
+ rb_erase_cached(&p->node, &execlists->queue);
+ i915_priolist_free(p);
+ }
+out:
+ if (!submit)
+ return false;
+
+ execlists->switch_priority_hint = switch_prio(engine, last);
+
+ ring_set_paused(engine, 1);
+
+ if (i915_request_completed(first)) {
+ execlists->pending[0] = execlists_schedule_in(last, 0);
+ execlists->pending[1] = NULL;
+
+ execlists_submit_ports(engine);
+ set_preempt_timeout(engine);
+ } else {
+ struct i915_request **port;
+
+ execlists_update_context(last);
+ for (port = execlists->inflight; *port != first; port++)
+ ;
+ WRITE_ONCE(*port, i915_request_get(last));
+ i915_request_put(first);
+ }
+
+ ring_set_paused(engine, 0);
+ return true;
+}
+
static void execlists_dequeue(struct intel_engine_cs *engine)
{
struct intel_engine_execlists * const execlists = &engine->execlists;
@@ -1907,6 +1961,9 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
return;
}
+
+ if (skip_lite_restore(engine, last))
+ return;
}
}
@@ -4107,6 +4164,16 @@ static u32 *emit_preempt_busywait(struct i915_request *request, u32 *cs)
return cs;
}
+static u32 *emit_lrm_tail(struct i915_request *request, u32 *cs)
+{
+ *cs++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_USE_GGTT;
+ *cs++ = i915_mmio_reg_offset(RING_TAIL(request->engine->mmio_base));
+ *cs++ = i915_ggtt_offset(request->context->state) + 4096 + CTX_RING_TAIL * sizeof(u32);
+ *cs++ = 0;
+
+ return cs;
+}
+
static __always_inline u32*
gen8_emit_fini_breadcrumb_footer(struct i915_request *request,
u32 *cs)
@@ -4114,8 +4181,10 @@ gen8_emit_fini_breadcrumb_footer(struct i915_request *request,
*cs++ = MI_USER_INTERRUPT;
*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
- if (intel_engine_has_semaphores(request->engine))
+ if (intel_engine_has_semaphores(request->engine)) {
cs = emit_preempt_busywait(request, cs);
+ cs = emit_lrm_tail(request, cs);
+ }
request->tail = intel_ring_offset(request, cs);
assert_ring_tail_valid(request->ring, request->tail);
--
2.25.0
More information about the Intel-gfx-trybot
mailing list