[PATCH 36/52] drm/i915: Reduce presumption of request ordering for barriers
Chris Wilson
chris at chris-wilson.co.uk
Sun Jan 27 18:25:40 UTC 2019
---
drivers/gpu/drm/i915/i915_drv.h | 3 ++
drivers/gpu/drm/i915/i915_gem_context.c | 66 ++-----------------------
drivers/gpu/drm/i915/i915_request.c | 1 +
drivers/gpu/drm/i915/intel_engine_cs.c | 5 ++
4 files changed, 14 insertions(+), 61 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4a2387f89eb0..eb04017a66ca 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1988,6 +1988,7 @@ struct drm_i915_private {
struct list_head active_rings;
struct list_head closed_vma;
+ unsigned long active_engines;
u32 active_requests;
/**
@@ -2097,6 +2098,8 @@ static inline struct drm_i915_private *huc_to_i915(struct intel_huc *huc)
(tmp__) ? \
((engine__) = (dev_priv__)->engine[__mask_next_bit(tmp__)]), 1 : \
0;)
+#define for_each_active_engine(engine__, i915__, tmp__) \
+ for_each_engine_masked((engine__), (i915__), (i915__)->gt.active_engines, (tmp__))
enum hdmi_force_audio {
HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index ea8e818d22bf..4a19382ac820 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -666,80 +666,25 @@ last_request_on_engine(struct i915_timeline *timeline,
return NULL;
}
-static bool engine_has_kernel_context_barrier(struct intel_engine_cs *engine)
-{
- struct drm_i915_private *i915 = engine->i915;
- const struct intel_context * const ce =
- to_intel_context(i915->kernel_context, engine);
- struct i915_timeline *barrier = ce->ring->timeline;
- struct intel_ring *ring;
- bool any_active = false;
-
- lockdep_assert_held(&i915->drm.struct_mutex);
- list_for_each_entry(ring, &i915->gt.active_rings, active_link) {
- struct i915_request *rq;
-
- rq = last_request_on_engine(ring->timeline, engine);
- if (!rq)
- continue;
-
- any_active = true;
-
- if (rq->hw_context == ce)
- continue;
-
- /*
- * Was this request submitted after the previous
- * switch-to-kernel-context?
- */
- if (!i915_timeline_sync_is_later(barrier, &rq->fence)) {
- GEM_TRACE("%s needs barrier for %llx:%lld\n",
- ring->timeline->name,
- rq->fence.context,
- rq->fence.seqno);
- return false;
- }
-
- GEM_TRACE("%s has barrier after %llx:%lld\n",
- ring->timeline->name,
- rq->fence.context,
- rq->fence.seqno);
- }
-
- /*
- * If any other timeline was still active and behind the last barrier,
- * then our last switch-to-kernel-context must still be queued and
- * will run last (leaving the engine in the kernel context when it
- * eventually idles).
- */
- if (any_active)
- return true;
-
- /* The engine is idle; check that it is idling in the kernel context. */
- return engine->last_retired_context == ce;
-}
-
int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915)
{
struct intel_engine_cs *engine;
- enum intel_engine_id id;
+ unsigned long tmp;
GEM_TRACE("awake?=%s\n", yesno(i915->gt.awake));
lockdep_assert_held(&i915->drm.struct_mutex);
GEM_BUG_ON(!i915->kernel_context);
- i915_retire_requests(i915);
+ /* Inoperable, so presume the GPU is safely pointing into the void! */
+ if (i915_terminally_wedged(&i915->gpu_error))
+ return 0;
- for_each_engine(engine, i915, id) {
+ for_each_active_engine(engine, i915, tmp) {
struct intel_ring *ring;
struct i915_request *rq;
GEM_BUG_ON(!to_intel_context(i915->kernel_context, engine));
- if (engine_has_kernel_context_barrier(engine))
- continue;
-
- GEM_TRACE("emit barrier on %s\n", engine->name);
rq = i915_request_alloc(engine, i915->kernel_context);
if (IS_ERR(rq))
@@ -763,7 +708,6 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915)
i915_sw_fence_await_sw_fence_gfp(&rq->submit,
&prev->submit,
I915_FENCE_GFP);
- i915_timeline_sync_set(rq->timeline, &prev->fence);
}
i915_request_add(rq);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 77d4dbfcf80f..559794e9ee0e 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -1069,6 +1069,7 @@ void i915_request_add(struct i915_request *request)
GEM_TRACE("marking %s as active\n", ring->timeline->name);
list_add(&ring->active_link, &request->i915->gt.active_rings);
}
+ request->i915->gt.active_engines |= request->engine->mask;
request->emitted_jiffies = jiffies;
/*
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index f6b7398d4710..d174e1ffbeaf 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1074,6 +1074,9 @@ bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine)
lockdep_assert_held(&engine->i915->drm.struct_mutex);
+ if (!engine->context_size)
+ return true;
+
/*
* Check the last context seen by the engine. If active, it will be
* the last request that remains in the timeline. When idle, it is
@@ -1173,6 +1176,8 @@ void intel_engines_park(struct drm_i915_private *i915)
i915_gem_batch_pool_fini(&engine->batch_pool);
engine->execlists.no_priolist = false;
}
+
+ i915->gt.active_engines = 0;
}
/**
--
2.20.1
More information about the Intel-gfx-trybot
mailing list