drm/i915: Skip waking the signaler when enabling before request submission
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 26 Apr 2017 08:06:59 +0000 (09:06 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 26 Apr 2017 10:51:31 +0000 (11:51 +0100)
If we are enabling the breadcrumbs signaling prior to submitting the
request, we know that we cannot have missed the interrupt and can
therefore skip immediately waking the signaler to check.

This reduces a significant chunk of the __i915_gem_request_submit()
overhead for inter-engine synchronisation, for example in gem_exec_whisper.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170426080659.28771-1-chris@chris-wilson.co.uk
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_guc_submission.c
drivers/gpu/drm/i915/intel_breadcrumbs.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 126cd13abf54a334196e9a9d23dfa259441370f9..6198f6997d055080b2df99e3dc941c3f0de06225 100644 (file)
@@ -61,7 +61,7 @@ static bool i915_fence_enable_signaling(struct dma_fence *fence)
        if (i915_fence_signaled(fence))
                return false;
 
-       intel_engine_enable_signaling(to_request(fence));
+       intel_engine_enable_signaling(to_request(fence), true);
        return true;
 }
 
@@ -437,7 +437,7 @@ void __i915_gem_request_submit(struct drm_i915_gem_request *request)
        spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
        request->global_seqno = seqno;
        if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
-               intel_engine_enable_signaling(request);
+               intel_engine_enable_signaling(request, false);
        spin_unlock(&request->lock);
 
        engine->emit_breadcrumb(request,
index ab5140ba108ddcb2c9c5382cc6439223704f9fda..4cc97bf1bdacbb69569c2e519237eb0bc5c55480 100644 (file)
@@ -649,7 +649,7 @@ static void nested_enable_signaling(struct drm_i915_gem_request *rq)
        trace_dma_fence_enable_signal(&rq->fence);
 
        spin_lock_nested(&rq->lock, SINGLE_DEPTH_NESTING);
-       intel_engine_enable_signaling(rq);
+       intel_engine_enable_signaling(rq, true);
        spin_unlock(&rq->lock);
 }
 
index 35da5928bd8a37cc96fe1a3a63829a35a646133b..183afcb036aa915ecde8b33ce7b83195f9c9c519 100644 (file)
@@ -667,12 +667,13 @@ static int intel_breadcrumbs_signaler(void *arg)
        return 0;
 }
 
-void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
+void intel_engine_enable_signaling(struct drm_i915_gem_request *request,
+                                  bool wakeup)
 {
        struct intel_engine_cs *engine = request->engine;
        struct intel_breadcrumbs *b = &engine->breadcrumbs;
        struct rb_node *parent, **p;
-       bool first, wakeup;
+       bool first;
        u32 seqno;
 
        /* Note that we may be called from an interrupt handler on another
@@ -705,7 +706,7 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
         * If we are the oldest waiter, enable the irq (after which we
         * must double check that the seqno did not complete).
         */
-       wakeup = __intel_engine_add_wait(engine, &request->signaling.wait);
+       wakeup &= __intel_engine_add_wait(engine, &request->signaling.wait);
 
        /* Now insert ourselves into the retirement ordered list of signals
         * on this engine. We track the oldest seqno as that will be the
index 96710b616efb59f9dc38f454b9f3526c0a68b6b8..2506bbe26fa0c393abe1ad2dff08bf143b68e012 100644 (file)
@@ -672,7 +672,8 @@ bool intel_engine_add_wait(struct intel_engine_cs *engine,
                           struct intel_wait *wait);
 void intel_engine_remove_wait(struct intel_engine_cs *engine,
                              struct intel_wait *wait);
-void intel_engine_enable_signaling(struct drm_i915_gem_request *request);
+void intel_engine_enable_signaling(struct drm_i915_gem_request *request,
+                                  bool wakeup);
 void intel_engine_cancel_signaling(struct drm_i915_gem_request *request);
 
 static inline bool intel_engine_has_waiter(const struct intel_engine_cs *engine)