Limit busywaiting only to the request currently being processed by the GPU. If the request is not currently being processed by the GPU, there is a very low likelihood of it being completed within the 2 microsecond spin timeout and so we will just be wasting CPU cycles. v2: Check for logical inversion when rebasing - we were incorrectly checking for this request being active, and instead busywaiting for when the GPU was not yet processing the request of interest. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@xxxxxxxxx> Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxxxxxxxx> Cc: Eero Tamminen <eero.t.tamminen@xxxxxxxxx> Cc: "Rantala, Valtteri" <valtteri.rantala@xxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 25 +++++++++++++++---------- drivers/gpu/drm/i915/i915_gem.c | 12 +++++++++--- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/i915_guc_submission.c | 2 +- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a3b22bdacd44..f0aeafbcf307 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -710,7 +710,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data) if (req->pid) task = pid_task(req->pid, PIDTYPE_PID); seq_printf(m, " %x @ %d: %s [%d]\n", - req->seqno, + req->seqno_complete, (int) (jiffies - req->emitted_jiffies), task ? task->comm : "<unknown>", task ? task->pid : -1); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 95bb27de774f..19986bd032ef 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2192,8 +2192,12 @@ struct drm_i915_gem_request { struct drm_i915_private *i915; struct intel_engine_cs *ring; - /** GEM sequence number associated with this request. */ - uint32_t seqno; + /* GEM sequence numbers associated with this request: + * active - marks the start of the request, passed when + * the GPU completes the previous request + * complete - marks the end of the request + */ + u32 seqno_active, seqno_complete; /** Position in the ringbuffer of the start of the request */ u32 head; @@ -2270,7 +2274,7 @@ int i915_gem_request_add_to_client(struct drm_i915_gem_request *req, static inline uint32_t i915_gem_request_get_seqno(struct drm_i915_gem_request *req) { - return req ? req->seqno : 0; + return req ? req->seqno_complete : 0; } static inline struct intel_engine_cs * @@ -2909,16 +2913,17 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) return (int32_t)(seq1 - seq2) >= 0; } +static inline bool i915_gem_request_active(struct drm_i915_gem_request *req) +{ + u32 seqno = req->ring->get_seqno(req->ring, true); + return i915_seqno_passed(seqno, req->seqno_active); +} + static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req, bool lazy_coherency) { - u32 seqno; - - BUG_ON(req == NULL); - - seqno = req->ring->get_seqno(req->ring, lazy_coherency); - - return i915_seqno_passed(seqno, req->seqno); + u32 seqno = req->ring->get_seqno(req->ring, lazy_coherency); + return i915_seqno_passed(seqno, req->seqno_complete); } int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c0941e8a70f7..490840324e88 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1193,9 +1193,14 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state) * takes to sleep on a request, on the order of a microsecond. */ - if (i915_gem_request_get_ring(req)->irq_refcount) + if (req->ring->irq_refcount) return -EBUSY; + /* Only spin if we know the GPU is processing this request */ + if (!i915_seqno_passed(req->ring->get_seqno(req->ring, false), + req->seqno_active)) + return -EAGAIN; + timeout = local_clock_us(&cpu) + 10; while (!need_resched()) { if (i915_gem_request_completed(req, true)) @@ -2592,7 +2597,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, request->batch_obj = obj; request->emitted_jiffies = jiffies; - ring->last_submitted_seqno = request->seqno; + request->seqno_active = ring->last_submitted_seqno; + ring->last_submitted_seqno = request->seqno_complete; list_add_tail(&request->list, &ring->request_list); trace_i915_gem_request_add(request); @@ -2691,7 +2697,7 @@ int i915_gem_request_alloc(struct intel_engine_cs *ring, if (req == NULL) return -ENOMEM; - ret = i915_gem_get_seqno(ring->dev, &req->seqno); + ret = i915_gem_get_seqno(ring->dev, &req->seqno_complete); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 2f04e4f2ff35..33501499bf51 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1072,7 +1072,7 @@ static void i915_gem_record_rings(struct drm_device *dev, struct drm_i915_error_request *erq; erq = &error->ring[i].requests[count++]; - erq->seqno = request->seqno; + erq->seqno = request->seqno_complete; erq->jiffies = request->emitted_jiffies; erq->tail = request->postfix; } diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 036b42bae827..d313e1938d58 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -625,7 +625,7 @@ int i915_guc_submit(struct i915_guc_client *client, spin_lock(&guc->host2guc_lock); guc->submissions[ring_id] += 1; - guc->last_seqno[ring_id] = rq->seqno; + guc->last_seqno[ring_id] = rq->seqno_complete; spin_unlock(&guc->host2guc_lock); return q_ret; -- 2.6.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx