drm/i915: Improve fallback ring waiting
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 5 May 2014 08:07:32 +0000 (09:07 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 7 May 2014 23:22:34 +0000 (01:22 +0200)
A few improvements to the fallback method for waiting upon ring space:

1. Fix the start/end wait tracepoints to always be paired.
2. Increase responsiveness of checking
3. Mark the process as waiting upon io
4. Check for signal interruptions

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Brad Volkin <bradley.d.volkin@intel.com>
[danvet: Drop the s/msleep/io_schedule_timeout/ change again since the
latter isn't exported.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_ringbuffer.c

index 40a7aa4db589b2293dc89fdb280872e5c710a4a1..e6c7a4dfea51f25c61aaa3a0aa4063da0bb57850 100644 (file)
@@ -1546,7 +1546,6 @@ static int ring_wait_for_space(struct intel_ring_buffer *ring, int n)
        /* force the tail write in case we have been skipping them */
        __intel_ring_advance(ring);
 
-       trace_i915_ring_wait_begin(ring);
        /* With GEM the hangcheck timer should kick us out of the loop,
         * leaving it early runs the risk of corrupting GEM state (due
         * to running on almost untested codepaths). But on resume
@@ -1554,12 +1553,13 @@ static int ring_wait_for_space(struct intel_ring_buffer *ring, int n)
         * case by choosing an insanely large timeout. */
        end = jiffies + 60 * HZ;
 
+       trace_i915_ring_wait_begin(ring);
        do {
                ring->head = I915_READ_HEAD(ring);
                ring->space = ring_space(ring);
                if (ring->space >= n) {
-                       trace_i915_ring_wait_end(ring);
-                       return 0;
+                       ret = 0;
+                       break;
                }
 
                if (!drm_core_check_feature(dev, DRIVER_MODESET) &&
@@ -1571,13 +1571,23 @@ static int ring_wait_for_space(struct intel_ring_buffer *ring, int n)
 
                msleep(1);
 
+               if (dev_priv->mm.interruptible && signal_pending(current)) {
+                       ret = -ERESTARTSYS;
+                       break;
+               }
+
                ret = i915_gem_check_wedge(&dev_priv->gpu_error,
                                           dev_priv->mm.interruptible);
                if (ret)
-                       return ret;
-       } while (!time_after(jiffies, end));
+                       break;
+
+               if (time_after(jiffies, end)) {
+                       ret = -EBUSY;
+                       break;
+               }
+       } while (1);
        trace_i915_ring_wait_end(ring);
-       return -EBUSY;
+       return ret;
 }
 
 static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)