[Intel-gfx] [PATCH v2 1/2] drm/i915: signal first fence from irq handler if complete
Chris Wilson
chris at chris-wilson.co.uk
Fri Feb 24 10:19:07 UTC 2017
On Fri, Feb 24, 2017 at 10:04:23AM +0000, Tvrtko Ursulin wrote:
>
> On 23/02/2017 15:42, Chris Wilson wrote:
> >diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
> >index 5f73d8c0a38a..0efee879df23 100644
> >--- a/drivers/gpu/drm/i915/i915_gem_request.h
> >+++ b/drivers/gpu/drm/i915/i915_gem_request.h
> >@@ -32,10 +32,12 @@
> >
> > struct drm_file;
> > struct drm_i915_gem_object;
> >+struct drm_i915_gem_request;
> >
> > struct intel_wait {
> > struct rb_node node;
> > struct task_struct *tsk;
> >+ struct drm_i915_gem_request *request;
> > u32 seqno;
>
> Hm, do we now have a situation where both waiters and signallers
> hold a reference to the request so could drop the seqno field from
> here?
Keeping the seqno field helps with the lowlevel testcase that works
without requests. Not scientific, but it was one less pointer for the
irq handler.
> > };
> >
> >diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> >index bc70e2c451b2..3c79753edf0e 100644
> >--- a/drivers/gpu/drm/i915/i915_irq.c
> >+++ b/drivers/gpu/drm/i915/i915_irq.c
> >@@ -1033,12 +1033,41 @@ static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv)
> >
> > static void notify_ring(struct intel_engine_cs *engine)
> > {
> >- bool waiters;
> >+ struct drm_i915_gem_request *rq = NULL;
> >+ struct intel_wait *wait;
> >+
> >+ if (!intel_engine_has_waiter(engine))
> >+ return;
>
> I think we need the tracepoint before the bail out.
>
> >
> > atomic_inc(&engine->irq_count);
>
> And the increment as well.
>
> > set_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
> >- waiters = intel_engine_wakeup(engine);
> >- trace_intel_engine_notify(engine, waiters);
> >+
> >+ spin_lock(&engine->breadcrumbs.lock);
> >+ wait = engine->breadcrumbs.first_wait;
> >+ if (wait) {
> >+ /* We use a callback from the dma-fence to submit
> >+ * requests after waiting on our own requests. To
> >+ * ensure minimum delay in queuing the next request to
> >+ * hardware, signal the fence now rather than wait for
> >+ * the signaler to be woken up. We still wake up the
> >+ * waiter in order to handle the irq-seqno coherency
> >+ * issues (we may receive the interrupt before the
> >+ * seqno is written, see __i915_request_irq_complete())
> >+ * and to handle coalescing of multiple seqno updates
> >+ * and many waiters.
> >+ */
> >+ if (i915_seqno_passed(intel_engine_get_seqno(engine),
> >+ wait->seqno))
> >+ rq = wait->request;
> >+
> >+ wake_up_process(wait->tsk);
> >+ }
> >+ spin_unlock(&engine->breadcrumbs.lock);
> >+
> >+ if (rq) /* rq is protected by RCU, so safe from hard-irq context */
> >+ dma_fence_signal(&rq->fence);
> >+
> >+ trace_intel_engine_notify(engine, wait);
Hmm, I put the trace here for access to wait. I guess we only need a
READ_ONCE(engine->breadcrumbs.first_wait) for tracking?
Note in the next patch, it's different again. And yeah I should massage
it such that it doesn't introduce a fluctuation.
> > }
> >
> > static void vlv_c0_read(struct drm_i915_private *dev_priv,
> >diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> >index 027c93e34c97..5f2665aa817c 100644
> >--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
> >+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> >@@ -81,8 +81,11 @@ static void intel_breadcrumbs_fake_irq(unsigned long data)
> > * every jiffie in order to kick the oldest waiter to do the
> > * coherent seqno check.
> > */
> >- if (intel_engine_wakeup(engine))
> >- mod_timer(&engine->breadcrumbs.fake_irq, jiffies + 1);
> >+ if (!intel_engine_has_waiter(engine))
> >+ return;
> >+
> >+ intel_engine_wakeup(engine);
> >+ mod_timer(&engine->breadcrumbs.fake_irq, jiffies + 1);
>
> Not sure it is worth splitting this in two instead of just leaving
> it as it was.
The problem with the previous code was the timer stopped if the waiter
was running at that moment. I am still playing to find something that
doesn't look horrible. Just going back to the bool intel_engine_wakeup,
which is now far too large to be an inline for an unimportant function.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list