summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Harrison <John.C.Harrison@Intel.com>2015-07-13 17:25:22 +0100
committerJohn Harrison <John.C.Harrison@Intel.com>2016-06-30 15:06:27 +0100
commita72c85736a9417ada1b1d12f4af524eca17e4b6e (patch)
treeaa587dcdd3c9d1a1e88d6f2ac44e251674e25e6a
parent487a1260d8a753fd3c123664d97e7b31c87cbd52 (diff)
drm/i915: Add per context timelines for fence objects
The purpose of this patch series is to convert the requst structure to use fence objects for the underlying completion tracking. The fence object requires a sequence number. The ultimate aim is to use the same sequence number as for the request itself (or rather, to remove the request's seqno field and just use the fence's value throughout the driver). However, this is not currently possible and so this patch introduces a separate numbering scheme as an intermediate step. A major advantage of using the fence object is that it can be passed outside of the i915 driver and used externally. The fence API allows for various operations such as combining multiple fences. This requires that fence seqnos within a single fence context be guaranteed in-order. The GPU scheduler that is coming can re-order request execution but not within a single GPU context. Thus the fence context must be tied to the i915 context (and the engine within the context as each engine runs asynchronously). On the other hand, the driver as a whole currently only works with request seqnos that are allocated from a global in-order timeline. It will require a fair chunk of re-work to allow multiple independent seqno timelines to be used. Hence the introduction of a temporary, fence specific timeline. Once the work to update the rest of the driver has been completed then the request can use the fence seqno instead. v2: New patch in series. v3: Renamed/retyped timeline structure fields after review comments by Tvrtko Ursulin. Added context information to the timeline's name string for better identification in debugfs output. v5: Line wrapping and other white space fixes to keep style checker happy. v7: Updated to newer nightly (lots of ring -> engine renaming). v8: Moved to earlier in patch series so no longer needs to remove the quick hack timeline that was being added before. v9: Updated to another newer nightly (changes to context structure naming). Also updated commit message to match previous changes. v10: Removed obsolete fields from timeline structure and a couple of functions. Corrected some comments and debug prints. [Review comments from Maarten Lankhorst & Tvrtko Ursulin] Updated to yet more nightly changes (u64 for fence context). For: VIZ-5190 Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h10
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c36
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c16
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c8
4 files changed, 70 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 53d9e3fab489..ca67b455b67f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -831,6 +831,15 @@ struct i915_ctx_hang_stats {
bool banned;
};
+struct i915_fence_timeline {
+ char name[32];
+ u64 fence_context;
+ unsigned next;
+};
+
+int i915_create_fence_timeline(struct i915_gem_context *ctx,
+ struct intel_engine_cs *ring);
+
/* This must match up with the value previously used for execbuf2.rsvd1. */
#define DEFAULT_CONTEXT_HANDLE 0
@@ -875,6 +884,7 @@ struct i915_gem_context {
u64 lrc_desc;
int pin_count;
bool initialised;
+ struct i915_fence_timeline fence_timeline;
} engine[I915_NUM_ENGINES];
struct list_head link;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index eae8d7a89d09..ed45586f0972 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2772,6 +2772,42 @@ void i915_gem_request_free(struct kref *req_ref)
kmem_cache_free(req->i915->requests, req);
}
+int i915_create_fence_timeline(struct i915_gem_context *ctx,
+ struct intel_engine_cs *engine)
+{
+ struct i915_fence_timeline *timeline;
+
+ timeline = &ctx->engine[engine->id].fence_timeline;
+
+ WARN_ON(timeline->name[0]);
+
+ timeline->fence_context = fence_context_alloc(1);
+
+ /*
+ * Start the timeline from seqno 1 as zero is a special value
+ * that is reserved for invalid sync points.
+ */
+ timeline->next = 1;
+
+ snprintf(timeline->name, sizeof(timeline->name), "%lld>%s:%d",
+ timeline->fence_context, engine->name, ctx->user_handle);
+
+ return 0;
+}
+
+unsigned i915_fence_timeline_get_next_seqno(struct i915_fence_timeline *timeline)
+{
+ unsigned seqno;
+
+ seqno = timeline->next;
+
+ /* Reserve zero for invalid */
+ if (++timeline->next == 0)
+ timeline->next = 1;
+
+ return seqno;
+}
+
static inline int
__i915_gem_request_alloc(struct intel_engine_cs *engine,
struct i915_gem_context *ctx,
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a3b11aac23a4..a807c4ab36c3 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -320,6 +320,22 @@ i915_gem_create_context(struct drm_device *dev,
if (IS_ERR(ctx))
return ctx;
+ if (!i915.enable_execlists) {
+ struct intel_engine_cs *engine;
+
+ /* Create a per context timeline for fences */
+ for_each_engine(engine, to_i915(dev)) {
+ int ret = i915_create_fence_timeline(ctx, engine);
+ if (ret) {
+ DRM_ERROR("Fence timeline creation failed for legacy %s: %p/%d\n",
+ engine->name, ctx, ctx->user_handle);
+ idr_remove(&file_priv->context_idr, ctx->user_handle);
+ i915_gem_context_unreference(ctx);
+ return ERR_PTR(ret);
+ }
+ }
+ }
+
if (USES_FULL_PPGTT(dev)) {
struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 4fad8303648e..dedb3f85629b 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2539,6 +2539,14 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
goto error_ringbuf;
}
+ /* Create a per context timeline for fences */
+ ret = i915_create_fence_timeline(ctx, engine);
+ if (ret) {
+ DRM_ERROR("Fence timeline creation failed for %s, ctx %p/%d\n",
+ engine->name, ctx, ctx->user_handle);
+ goto error_ringbuf;
+ }
+
ce->ringbuf = ringbuf;
ce->state = ctx_obj;
ce->initialised = engine->init_context == NULL;