Skip to content

Commit

Permalink
drm/i915: Protect active fences on i915
Browse files Browse the repository at this point in the history
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@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
  • Loading branch information
Chris Wilson authored and Eric Anholt committed Mar 11, 2009
1 parent fc7170b commit d7619c4
Showing 1 changed file with 31 additions and 7 deletions.
38 changes: 31 additions & 7 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1595,34 +1595,58 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write)

/* 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;
}

/*
* Now things get ugly... we have to wait for one of the
* objects to finish before trying again.
*/
if (i == dev_priv->num_fence_regs) {
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.
Expand Down

0 comments on commit d7619c4

Please sign in to comment.