diff options
author | Jonathan Gray <jsg@jsg.id.au> | 2013-03-11 15:12:34 +1100 |
---|---|---|
committer | Jonathan Gray <jsg@jsg.id.au> | 2013-03-11 15:12:34 +1100 |
commit | 8a31e40677c4911deee514ea3d47b1a5f582e3f8 (patch) | |
tree | 20e34e65d2091bdcc3a74594f4d47d6fe938c613 | |
parent | 4b81d3820ad1a618460a92093a773c5478a33770 (diff) |
split wait_seqno into two functions and drop the retire requests call
-rw-r--r-- | sys/dev/pci/drm/i915_gem.c | 61 | ||||
-rw-r--r-- | sys/dev/pci/drm/intel_overlay.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/intel_ringbuffer.c | 3 |
3 files changed, 42 insertions, 24 deletions
diff --git a/sys/dev/pci/drm/i915_gem.c b/sys/dev/pci/drm/i915_gem.c index ef34c19a734..97508030b19 100644 --- a/sys/dev/pci/drm/i915_gem.c +++ b/sys/dev/pci/drm/i915_gem.c @@ -82,6 +82,7 @@ void i915_gem_object_truncate(struct drm_i915_gem_object *obj); int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, unsigned alignment, bool map_and_fenceable); int i915_gem_wait_for_error(struct drm_device *); +int __wait_seqno(struct intel_ring_buffer *, uint32_t, bool, struct timespec *); extern int ticks; @@ -498,30 +499,24 @@ i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno) return ret; } -// __wait_seqno - /** - * Waits for a sequence number to be signaled, and cleans up the - * request and object lists appropriately for that event. + * __wait_seqno - wait until execution of seqno has finished + * @ring: the ring expected to report seqno + * @seqno: duh! + * @interruptible: do an interruptible wait (normally yes) + * @timeout: in - how long to wait (NULL forever); out - how much time remaining * - * Called locked, sleeps with it. + * Returns 0 if the seqno was found within the alloted time. Else returns the + * errno with remaining time filled in timeout argument. */ int -i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) +__wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno, + bool interruptible, struct timespec *timeout) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; int ret = 0; - /* Check first because poking a wedged chip is bad. */ - ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible); - if (ret) - return (ret); - - ret = i915_gem_check_olr(ring, seqno); - if (ret) - return ret; - mtx_enter(&dev_priv->irq_lock); if (!i915_seqno_passed(ring->get_seqno(ring, true), seqno)) { ring->irq_get(ring); @@ -530,7 +525,7 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) seqno) || dev_priv->mm.wedged) break; ret = msleep(ring, &dev_priv->irq_lock, - PZERO | (dev_priv->mm.interruptible ? PCATCH : 0), + PZERO | (interruptible ? PCATCH : 0), "gemwt", 0); } ring->irq_put(ring); @@ -539,17 +534,35 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) if (dev_priv->mm.wedged) ret = EIO; - /* Directly dispatch request retiring. While we have the work queue - * to handle this, the waiter on a request often wants an associated - * buffer to have made it to the inactive list, and we would need - * a separate wait queue to handle that. - */ - if (ret == 0) - i915_gem_retire_requests_ring(ring); - return (ret); } +/** + * Waits for a sequence number to be signaled, and cleans up the + * request and object lists appropriately for that event. + */ +int +i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) +{ + struct drm_device *dev = ring->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + bool interruptible = dev_priv->mm.interruptible; + int ret; + +// BUG_ON(!mutex_is_locked(&dev->struct_mutex)); + BUG_ON(seqno == 0); + + ret = i915_gem_check_wedge(dev_priv, interruptible); + if (ret) + return (ret); + + ret = i915_gem_check_olr(ring, seqno); + if (ret) + return ret; + + return __wait_seqno(ring, seqno, interruptible, NULL); +} + int i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, bool readonly) diff --git a/sys/dev/pci/drm/intel_overlay.c b/sys/dev/pci/drm/intel_overlay.c index a3bfb964cc9..e9039279520 100644 --- a/sys/dev/pci/drm/intel_overlay.c +++ b/sys/dev/pci/drm/intel_overlay.c @@ -296,6 +296,7 @@ intel_overlay_do_wait_request(struct intel_overlay *overlay, ret = i915_wait_seqno(ring, overlay->last_flip_req); if (ret) return ret; + i915_gem_retire_requests(dev_priv); overlay->last_flip_req = 0; return 0; @@ -448,6 +449,7 @@ intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) ret = i915_wait_seqno(ring, overlay->last_flip_req); if (ret) return ret; + i915_gem_retire_requests(dev_priv); if (overlay->flip_tail) overlay->flip_tail(overlay); diff --git a/sys/dev/pci/drm/intel_ringbuffer.c b/sys/dev/pci/drm/intel_ringbuffer.c index bda30f9546d..a5d8f65a1a1 100644 --- a/sys/dev/pci/drm/intel_ringbuffer.c +++ b/sys/dev/pci/drm/intel_ringbuffer.c @@ -1381,6 +1381,9 @@ intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) ret = i915_wait_seqno(ring, seqno); + if (!ret) + i915_gem_retire_requests_ring(ring); + dev_priv->mm.interruptible = was_interruptible; return ret; |