summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/selftests/mock_engine.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-04-30 16:15:02 +0300
committerChris Wilson <chris@chris-wilson.co.uk>2018-04-30 18:01:18 +0300
commitb887d61546245389c0304d8b1371bab9af8106c2 (patch)
treeeafb812bb0b18b188f9f9f3a211f03f24f8c240d /drivers/gpu/drm/i915/selftests/mock_engine.c
parentab82a0635cdf0b91a134aaae34abd4e864595c5b (diff)
downloadlinux-b887d61546245389c0304d8b1371bab9af8106c2.tar.xz
drm/i915: Retire requests along rings
In the next patch, rings are the central timeline as requests may jump between engines. Therefore in the future as we retire in order along the engine timeline, we may retire out-of-order within a ring (as the ring now occurs along multiple engines), leading to much hilarity in miscomputing the position of ring->head. As an added bonus, retiring along the ring reduces the penalty of having one execlists client do cleanup for another (old legacy submission shares a ring between all clients). The downside is that slow and irregular (off the critical path) process of cleaning up stale requests after userspace becomes a modicum less efficient. In the long run, it will become apparent that the ordered ring->request_list matches the ring->timeline, a fun challenge for the future will be unifying the two lists to avoid duplication! v2: We need both engine-order and ring-order processing to maintain our knowledge of where individual rings have completed upto as well as knowing what was last executing on any engine. And finally by decoupling retiring the contexts on the engine and the timelines along the rings, we do have to keep a reference to the context on each request (previously it was guaranteed by the context being pinned). v3: Not just a reference to the context, but we need to keep it pinned as we manipulate the rings; i.e. we need a pin for both the manipulation of the engine state during its retirements, and a separate pin for the manipulation of the ring state. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180430131503.5375-3-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/selftests/mock_engine.c')
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_engine.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index b82420c6b810..d95fc481e5c1 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -147,9 +147,18 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
INIT_LIST_HEAD(&ring->request_list);
intel_ring_update_space(ring);
+ list_add(&ring->link, &engine->i915->gt.rings);
+
return ring;
}
+static void mock_ring_free(struct intel_ring *ring)
+{
+ list_del(&ring->link);
+
+ kfree(ring);
+}
+
struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
const char *name,
int id)
@@ -162,12 +171,6 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
if (!engine)
return NULL;
- engine->base.buffer = mock_ring(&engine->base);
- if (!engine->base.buffer) {
- kfree(engine);
- return NULL;
- }
-
/* minimal engine setup for requests */
engine->base.i915 = i915;
snprintf(engine->base.name, sizeof(engine->base.name), "%s", name);
@@ -192,7 +195,16 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
timer_setup(&engine->hw_delay, hw_delay_complete, 0);
INIT_LIST_HEAD(&engine->hw_queue);
+ engine->base.buffer = mock_ring(&engine->base);
+ if (!engine->base.buffer)
+ goto err_breadcrumbs;
+
return &engine->base;
+
+err_breadcrumbs:
+ intel_engine_fini_breadcrumbs(&engine->base);
+ kfree(engine);
+ return NULL;
}
void mock_engine_flush(struct intel_engine_cs *engine)
@@ -226,8 +238,9 @@ void mock_engine_free(struct intel_engine_cs *engine)
if (engine->last_retired_context)
intel_context_unpin(engine->last_retired_context, engine);
+ mock_ring_free(engine->buffer);
+
intel_engine_fini_breadcrumbs(engine);
- kfree(engine->buffer);
kfree(engine);
}