[Intel-gfx] [PATCH] drm/i915: Protect active fences on i915
Chris Wilson
chris at chris-wilson.co.uk
Wed Feb 11 15:26:47 CET 2009
The i915 also uses the fence registers for GPU access to tiled buffers so
we cannot reallocate one whilst it is on the active list. By performing a
LRU scan of the fenced buffers we also avoid waiting the possibility of
waiting on a pinned, or otherwise unusable, buffer.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_gem.c | 42 ++++++++++++++++++++++++++++++--------
1 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 95e50c4..ade6c18 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1584,18 +1584,32 @@ try_again:
/* None available, try to steal one or wait for a user to finish */
if (i == dev_priv->num_fence_regs) {
+ uint32_t seqno = dev_priv->mm.next_gem_seqno;
loff_t offset;
if (avail == 0)
return -ENOMEM;
- /* Could try to use LRU here instead... */
for (i = dev_priv->fence_reg_start;
i < dev_priv->num_fence_regs; i++) {
+ uint32_t this_seqno;
+
reg = &dev_priv->fence_regs[i];
old_obj_priv = reg->obj->driver_private;
- if (!old_obj_priv->pin_count)
+
+ if (old_obj_priv->pin_count)
+ continue;
+
+ /* i915 uses fences for GPU access to tiled buffers */
+ if (IS_I965G(dev) || !old_obj_priv->active)
break;
+
+ /* find the seqno of the first available fence */
+ this_seqno = old_obj_priv->last_rendering_seqno;
+ if (this_seqno != 0 &&
+ reg->obj->write_domain == 0 &&
+ i915_seqno_passed(seqno, this_seqno))
+ seqno = this_seqno;
}
/*
@@ -1604,18 +1618,28 @@ try_again:
*/
if (i == dev_priv->num_fence_regs) {
#if WATCH_FENCE
- DRM_INFO("%s: waiting for fence (waiting on %p)\n",
- __func__, reg->obj);
+ DRM_INFO("%s: waiting for fence\n", __func__);
#endif
- ret = i915_gem_object_set_to_gtt_domain(reg->obj, 0);
- if (ret) {
- WARN(ret != -ERESTARTSYS,
- "switch to GTT domain failed: %d\n", ret);
- return ret;
+ if (seqno == dev_priv->mm.next_gem_seqno) {
+ i915_gem_flush(dev,
+ I915_GEM_GPU_DOMAINS,
+ I915_GEM_GPU_DOMAINS);
+ seqno = i915_add_request(dev,
+ I915_GEM_GPU_DOMAINS);
+ if (seqno == 0)
+ return -ENOMEM;
}
+
+ ret = i915_wait_request(dev, seqno);
+ if (ret)
+ return ret;
+
goto try_again;
}
+ BUG_ON(old_obj_priv->active ||
+ (reg->obj->write_domain & I915_GEM_GPU_DOMAINS));
+
/*
* Zap this virtual mapping so we can set up a fence again
* for this object next time we need it.
--
1.6.0.4
More information about the Intel-gfx
mailing list