i915: Fix i915 suspend delay
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Jan 2011 21:19:55 +0000 (13:19 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 Jan 2011 00:18:25 +0000 (16:18 -0800)
During system suspend, the "wait for ring buffer to empty" loop would
always time out after three seconds, because the faster cached ring
buffer head read would always return zero.  Force the slow-and-careful
PIO read on all but the first iterations of the loop to fix it.

This also removes the unused (and useless) 'actual_head' variable that
tried to approximate doing this, but did it incorrectly.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Dave Airlie <airlied@linux.ie>
Cc: DRI mailing list <dri-devel@lists.freedesktop.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h

index 03e3370725179bd14785aef19bf83f5c13c285ee..f6b9baa6a63dec8c0100f8ded5b6b80540d1a5a3 100644 (file)
@@ -928,6 +928,7 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
 
 int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
 {
+       int reread = 0;
        struct drm_device *dev = ring->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long end;
@@ -940,9 +941,8 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
                 * fallback to the slow and accurate path.
                 */
                head = intel_read_status_page(ring, 4);
-               if (head < ring->actual_head)
+               if (reread)
                        head = I915_READ_HEAD(ring);
-               ring->actual_head = head;
                ring->head = head & HEAD_ADDR;
                ring->space = ring->head - (ring->tail + 8);
                if (ring->space < 0)
@@ -961,6 +961,7 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
                msleep(1);
                if (atomic_read(&dev_priv->mm.wedged))
                        return -EAGAIN;
+               reread = 1;
        } while (!time_after(jiffies, end));
        trace_i915_ring_wait_end (dev);
        return -EBUSY;
index be9087e4c9beeb4c561ebc474a2b38a6124ce8cd..5b0abfa881fc7964eab452b5ea254e568ea49fe8 100644 (file)
@@ -47,7 +47,6 @@ struct  intel_ring_buffer {
        struct          drm_device *dev;
        struct          drm_i915_gem_object *obj;
 
-       u32             actual_head;
        u32             head;
        u32             tail;
        int             space;