This provides a nice boost to mesa in swap bound scenarios (as mesa throttles itself to the previous frame and given the scenario that will complete shortly). It will also provide a good boost to systems running with semaphores disabled and so frequently waiting on the GPU as it switches rings. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem.c | 43 +++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index de15bd319bd0..2aaa3cab2be4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1191,6 +1191,28 @@ static bool missed_irq(struct drm_i915_private *dev_priv, return test_bit(ring->id, &dev_priv->gpu_error.missed_irq_rings); } +static int __i915_spin_request(struct drm_i915_gem_request *req) +{ + struct intel_engine_cs *ring = i915_gem_request_get_ring(req); + struct drm_i915_private *dev_priv = to_i915(ring->dev); + int ret = -EBUSY; + + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + while (!need_resched()) { + if (i915_gem_request_completed(req, true)) { + ret = 0; + goto out; + } + + cpu_relax_lowlatency(); + } + if (i915_gem_request_completed(req, false)) + ret = 0; +out: + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); + return ret; +} + /** * __i915_wait_request - wait until execution of request has finished * @req: duh! @@ -1235,12 +1257,20 @@ int __i915_wait_request(struct drm_i915_gem_request *req, if (ring->id == RCS && INTEL_INFO(dev)->gen >= 6) gen6_rps_boost(dev_priv, file_priv); - if (!irq_test_in_progress && WARN_ON(!ring->irq_get(ring))) - return -ENODEV; - /* Record current time in case interrupted by signal, or wedged */ trace_i915_gem_request_wait_begin(req); before = ktime_get_raw_ns(); + + /* Optimistic spin before touching IRQs */ + ret = __i915_spin_request(req); + if (ret == 0) + goto out; + + if (!irq_test_in_progress && WARN_ON(!ring->irq_get(ring))) { + ret = -ENODEV; + goto out; + } + for (;;) { struct timer_list timer; @@ -1289,14 +1319,15 @@ int __i915_wait_request(struct drm_i915_gem_request *req, destroy_timer_on_stack(&timer); } } - now = ktime_get_raw_ns(); - trace_i915_gem_request_wait_end(req); - if (!irq_test_in_progress) ring->irq_put(ring); finish_wait(&ring->irq_queue, &wait); +out: + now = ktime_get_raw_ns(); + trace_i915_gem_request_wait_end(req); + if (timeout) { s64 tres = *timeout - (now - before); -- 2.1.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx