Message ID | 1466081680-2344-2-git-send-email-John.C.Harrison@Intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Op 16-06-16 om 14:54 schreef John.C.Harrison@Intel.com: > From: John Harrison <John.C.Harrison@Intel.com> > > 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> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 53d9e3f..ca67b45 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 57aa8a4..a3fdcf9 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 d0e7fc6..1971d8a 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 4fad830..dedb3f8 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;