summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2012-04-25 20:50:12 -0700
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-05-03 11:18:32 +0200
commitb4aca0106c466b5a0329318203f65bac2d91b682 (patch)
treec2babdee7cce61eefe1909650f188c0ab7f99db2
parentc921aba84ae5bf74b5386b4d2e01a5706ae4b878 (diff)
downloadblackbird-op-linux-b4aca0106c466b5a0329318203f65bac2d91b682.tar.gz
blackbird-op-linux-b4aca0106c466b5a0329318203f65bac2d91b682.zip
drm/i915: extract some common olr+wedge code
The new wait_rendering ioctl also needs to check for an oustanding lazy request, and we already duplicate that logic at three places. So extract it. While at it, also extract the code to check the gpu wedging state to improve code flow. v2: Don't use seqno as an outparam (Chris) v3 by danvet: Kill stale comment and pimp commit message Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c120
1 files changed, 63 insertions, 57 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 131eadb84adb..4ab57fd752dc 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1819,6 +1819,57 @@ i915_gem_retire_work_handler(struct work_struct *work)
mutex_unlock(&dev->struct_mutex);
}
+static int
+i915_gem_check_wedge(struct drm_i915_private *dev_priv)
+{
+ BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
+ if (atomic_read(&dev_priv->mm.wedged)) {
+ struct completion *x = &dev_priv->error_completion;
+ bool recovery_complete;
+ unsigned long flags;
+
+ /* Give the error handler a chance to run. */
+ spin_lock_irqsave(&x->wait.lock, flags);
+ recovery_complete = x->done > 0;
+ spin_unlock_irqrestore(&x->wait.lock, flags);
+
+ return recovery_complete ? -EIO : -EAGAIN;
+ }
+
+ return 0;
+}
+
+/*
+ * Compare seqno against outstanding lazy request. Emit a request if they are
+ * equal.
+ */
+static int
+i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno)
+{
+ int ret = 0;
+
+ BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
+
+ if (seqno == ring->outstanding_lazy_request) {
+ struct drm_i915_gem_request *request;
+
+ request = kzalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
+
+ ret = i915_add_request(ring, NULL, request);
+ if (ret) {
+ kfree(request);
+ return ret;
+ }
+
+ BUG_ON(seqno != request->seqno);
+ }
+
+ return ret;
+}
+
static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
bool interruptible)
{
@@ -1862,34 +1913,13 @@ i915_wait_request(struct intel_ring_buffer *ring,
BUG_ON(seqno == 0);
- if (atomic_read(&dev_priv->mm.wedged)) {
- struct completion *x = &dev_priv->error_completion;
- bool recovery_complete;
- unsigned long flags;
-
- /* Give the error handler a chance to run. */
- spin_lock_irqsave(&x->wait.lock, flags);
- recovery_complete = x->done > 0;
- spin_unlock_irqrestore(&x->wait.lock, flags);
-
- return recovery_complete ? -EIO : -EAGAIN;
- }
-
- if (seqno == ring->outstanding_lazy_request) {
- struct drm_i915_gem_request *request;
-
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
+ ret = i915_gem_check_wedge(dev_priv);
+ if (ret)
+ return ret;
- seqno = request->seqno;
- }
+ ret = i915_gem_check_olr(ring, seqno);
+ if (ret)
+ return ret;
ret = __wait_seqno(ring, seqno, dev_priv->mm.interruptible);
if (atomic_read(&dev_priv->mm.wedged))
@@ -1957,22 +1987,9 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
if (seqno <= from->sync_seqno[idx])
return 0;
- if (seqno == from->outstanding_lazy_request) {
- struct drm_i915_gem_request *request;
-
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
- ret = i915_add_request(from, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
-
- seqno = request->seqno;
- }
-
+ ret = i915_gem_check_olr(obj->ring, seqno);
+ if (ret)
+ return ret;
ret = to->sync_to(to, from, seqno);
if (!ret)
@@ -3160,20 +3177,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
ret = i915_gem_flush_ring(obj->ring,
0, obj->base.write_domain);
- } else if (obj->ring->outstanding_lazy_request ==
- obj->last_rendering_seqno) {
- struct drm_i915_gem_request *request;
-
- /* This ring is not being cleared by active usage,
- * so emit a request to do so.
- */
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request) {
- ret = i915_add_request(obj->ring, NULL, request);
- if (ret)
- kfree(request);
- } else
- ret = -ENOMEM;
+ } else {
+ ret = i915_gem_check_olr(obj->ring,
+ obj->last_rendering_seqno);
}
/* Update the active list for the hardware's current position.
OpenPOWER on IntegriCloud