summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@jsg.id.au>2013-03-11 15:12:34 +1100
committerJonathan Gray <jsg@jsg.id.au>2013-03-11 15:12:34 +1100
commit8a31e40677c4911deee514ea3d47b1a5f582e3f8 (patch)
tree20e34e65d2091bdcc3a74594f4d47d6fe938c613 /sys
parent4b81d3820ad1a618460a92093a773c5478a33770 (diff)
split wait_seqno into two functions and drop the retire requests call
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/drm/i915_gem.c61
-rw-r--r--sys/dev/pci/drm/intel_overlay.c2
-rw-r--r--sys/dev/pci/drm/intel_ringbuffer.c3
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;