Message ID | 20190806134725.25321-3-chris@chris-wilson.co.uk (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/5] drm/i915: Only enqueue already completed requests | expand |
Chris Wilson <chris@chris-wilson.co.uk> writes: > Sometimes we want to emit a terminator request, a request that flushes > the pipeline and allows no request to come after it. This can be used > for a "preempt-to-idle" to ensure that upon processing the > context-switch to that request, all other active contexts have been > flushed. > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > --- > drivers/gpu/drm/i915/gt/intel_lrc.c | 6 ++++++ > drivers/gpu/drm/i915/i915_request.h | 10 ++++++++-- > 2 files changed, 14 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c > index 4e45cd972267..59a7e4eb7e2a 100644 > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c > @@ -759,6 +759,9 @@ static bool can_merge_rq(const struct i915_request *prev, > GEM_BUG_ON(prev == next); > GEM_BUG_ON(!assert_priority_queue(prev, next)); > > + if (i915_request_has_sentinel(prev)) > + return false; > + > if (!can_merge_ctx(prev->hw_context, next->hw_context)) > return false; > > @@ -1250,6 +1253,9 @@ static void execlists_dequeue(struct intel_engine_cs *engine) > if (last->hw_context == rq->hw_context) > goto done; > > + if (i915_request_has_sentinel(last)) > + goto done; > + > /* > * If GVT overrides us we only ever submit > * port[0], leaving port[1] empty. Note that we > diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h > index 313df3c37158..c41ecbe0bd0c 100644 > --- a/drivers/gpu/drm/i915/i915_request.h > +++ b/drivers/gpu/drm/i915/i915_request.h > @@ -217,8 +217,9 @@ struct i915_request { > unsigned long emitted_jiffies; > > unsigned long flags; > -#define I915_REQUEST_WAITBOOST BIT(0) > -#define I915_REQUEST_NOPREEMPT BIT(1) > +#define I915_REQUEST_WAITBOOST BIT(0) > +#define I915_REQUEST_NOPREEMPT BIT(1) > +#define I915_REQUEST_SENTINEL BIT(2) Would it be possible to use 'empty' ie non payloadable requests as a sentinel? (using the request->postfix). Or is the advantage here that by attaching it as a property, you avoid submitting an extra (empty)? -Mika > > /** timeline->request entry for this request */ > struct list_head link; > @@ -443,6 +444,11 @@ static inline bool i915_request_has_nopreempt(const struct i915_request *rq) > return unlikely(rq->flags & I915_REQUEST_NOPREEMPT); > } > > +static inline bool i915_request_has_sentinel(const struct i915_request *rq) > +{ > + return unlikely(rq->flags & I915_REQUEST_SENTINEL); > +} > + > bool i915_retire_requests(struct drm_i915_private *i915); > > #endif /* I915_REQUEST_H */ > -- > 2.23.0.rc1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Quoting Mika Kuoppala (2019-08-06 15:29:58) > Chris Wilson <chris@chris-wilson.co.uk> writes: > > > Sometimes we want to emit a terminator request, a request that flushes > > the pipeline and allows no request to come after it. This can be used > > for a "preempt-to-idle" to ensure that upon processing the > > context-switch to that request, all other active contexts have been > > flushed. > > > > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> > > --- > > drivers/gpu/drm/i915/gt/intel_lrc.c | 6 ++++++ > > drivers/gpu/drm/i915/i915_request.h | 10 ++++++++-- > > 2 files changed, 14 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c > > index 4e45cd972267..59a7e4eb7e2a 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c > > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c > > @@ -759,6 +759,9 @@ static bool can_merge_rq(const struct i915_request *prev, > > GEM_BUG_ON(prev == next); > > GEM_BUG_ON(!assert_priority_queue(prev, next)); > > > > + if (i915_request_has_sentinel(prev)) > > + return false; > > + > > if (!can_merge_ctx(prev->hw_context, next->hw_context)) > > return false; > > > > @@ -1250,6 +1253,9 @@ static void execlists_dequeue(struct intel_engine_cs *engine) > > if (last->hw_context == rq->hw_context) > > goto done; > > > > + if (i915_request_has_sentinel(last)) > > + goto done; > > + > > /* > > * If GVT overrides us we only ever submit > > * port[0], leaving port[1] empty. Note that we > > diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h > > index 313df3c37158..c41ecbe0bd0c 100644 > > --- a/drivers/gpu/drm/i915/i915_request.h > > +++ b/drivers/gpu/drm/i915/i915_request.h > > @@ -217,8 +217,9 @@ struct i915_request { > > unsigned long emitted_jiffies; > > > > unsigned long flags; > > -#define I915_REQUEST_WAITBOOST BIT(0) > > -#define I915_REQUEST_NOPREEMPT BIT(1) > > +#define I915_REQUEST_WAITBOOST BIT(0) > > +#define I915_REQUEST_NOPREEMPT BIT(1) > > +#define I915_REQUEST_SENTINEL BIT(2) > > Would it be possible to use 'empty' ie non payloadable > requests as a sentinel? (using the request->postfix). > > Or is the advantage here that by attaching it as > a property, you avoid submitting an extra (empty)? To achieve the effect I want (effectively preempt-to-idle!), I need to fill the ELSP with dummies (N different contexts) to prevent submitting real requests after the preemption heartbeat. So I want an end-of-thread marker. I went through I915_REQUEST_EOT I915_REQUEST_TERMINATOR I915_REQEUST_SENTINEL -Chris
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 4e45cd972267..59a7e4eb7e2a 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -759,6 +759,9 @@ static bool can_merge_rq(const struct i915_request *prev, GEM_BUG_ON(prev == next); GEM_BUG_ON(!assert_priority_queue(prev, next)); + if (i915_request_has_sentinel(prev)) + return false; + if (!can_merge_ctx(prev->hw_context, next->hw_context)) return false; @@ -1250,6 +1253,9 @@ static void execlists_dequeue(struct intel_engine_cs *engine) if (last->hw_context == rq->hw_context) goto done; + if (i915_request_has_sentinel(last)) + goto done; + /* * If GVT overrides us we only ever submit * port[0], leaving port[1] empty. Note that we diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 313df3c37158..c41ecbe0bd0c 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -217,8 +217,9 @@ struct i915_request { unsigned long emitted_jiffies; unsigned long flags; -#define I915_REQUEST_WAITBOOST BIT(0) -#define I915_REQUEST_NOPREEMPT BIT(1) +#define I915_REQUEST_WAITBOOST BIT(0) +#define I915_REQUEST_NOPREEMPT BIT(1) +#define I915_REQUEST_SENTINEL BIT(2) /** timeline->request entry for this request */ struct list_head link; @@ -443,6 +444,11 @@ static inline bool i915_request_has_nopreempt(const struct i915_request *rq) return unlikely(rq->flags & I915_REQUEST_NOPREEMPT); } +static inline bool i915_request_has_sentinel(const struct i915_request *rq) +{ + return unlikely(rq->flags & I915_REQUEST_SENTINEL); +} + bool i915_retire_requests(struct drm_i915_private *i915); #endif /* I915_REQUEST_H */
Sometimes we want to emit a terminator request, a request that flushes the pipeline and allows no request to come after it. This can be used for a "preempt-to-idle" to ensure that upon processing the context-switch to that request, all other active contexts have been flushed. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> --- drivers/gpu/drm/i915/gt/intel_lrc.c | 6 ++++++ drivers/gpu/drm/i915/i915_request.h | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-)