drm/i915: Track the context's seqno in its own timeline HWSP
Now that we have allocated ourselves a cacheline to store a breadcrumb, we can emit a write from the GPU into the timeline's HWSP of the per-context seqno as we complete each request. This drops the mirroring of the per-engine HWSP and allows each context to operate independently. We do not need to unwind the per-context timeline, and so requests are always consistent with the timeline breadcrumb, greatly simplifying the completion checks as we no longer need to be concerned about the global_seqno changing mid check. One complication though is that we have to be wary that the request may outlive the HWSP and so avoid touching the potentially danging pointer after we have retired the fence. We also have to guard our access of the HWSP with RCU, the release of the obj->mm.pages should already be RCU-safe. At this point, we are emitting both per-context and global seqno and still using the single per-engine execution timeline for resolving interrupts. v2: s/fake_complete/mark_complete/ Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190128181812.22804-5-chris@chris-wilson.co.uk
This commit is contained in:
@@ -289,6 +289,7 @@ long i915_request_wait(struct i915_request *rq,
|
||||
|
||||
static inline bool i915_request_signaled(const struct i915_request *rq)
|
||||
{
|
||||
/* The request may live longer than its HWSP, so check flags first! */
|
||||
return test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags);
|
||||
}
|
||||
|
||||
@@ -340,32 +341,23 @@ static inline u32 hwsp_seqno(const struct i915_request *rq)
|
||||
*/
|
||||
static inline bool i915_request_started(const struct i915_request *rq)
|
||||
{
|
||||
u32 seqno;
|
||||
if (i915_request_signaled(rq))
|
||||
return true;
|
||||
|
||||
seqno = i915_request_global_seqno(rq);
|
||||
if (!seqno) /* not yet submitted to HW */
|
||||
return false;
|
||||
|
||||
return i915_seqno_passed(hwsp_seqno(rq), seqno - 1);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
__i915_request_completed(const struct i915_request *rq, u32 seqno)
|
||||
{
|
||||
GEM_BUG_ON(!seqno);
|
||||
return i915_seqno_passed(hwsp_seqno(rq), seqno) &&
|
||||
seqno == i915_request_global_seqno(rq);
|
||||
return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno - 1);
|
||||
}
|
||||
|
||||
static inline bool i915_request_completed(const struct i915_request *rq)
|
||||
{
|
||||
u32 seqno;
|
||||
if (i915_request_signaled(rq))
|
||||
return true;
|
||||
|
||||
seqno = i915_request_global_seqno(rq);
|
||||
if (!seqno)
|
||||
return false;
|
||||
return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno);
|
||||
}
|
||||
|
||||
return __i915_request_completed(rq, seqno);
|
||||
static inline void i915_request_mark_complete(struct i915_request *rq)
|
||||
{
|
||||
rq->hwsp_seqno = (u32 *)&rq->fence.seqno; /* decouple from HWSP */
|
||||
}
|
||||
|
||||
void i915_retire_requests(struct drm_i915_private *i915);
|
||||
|
Reference in New Issue
Block a user