aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-12-14 07:57:08 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-01-29 12:23:37 -0500
commit1690e1eb7a9021826853e181baa48dd77090da28 (patch)
tree397210ab6f278ca81b8108320768b39465db6d08 /drivers/gpu/drm/i915/i915_gem.c
parent6a233c78878d8795517d716544d045d5675b3061 (diff)
drm/i915: Separate fence pin counting from normal bind pin counting
In order to correctly account for reserving space in the GTT and fences for a batch buffer, we need to independently track whether the fence is pinned due to a fenced GPU access in the batch or whether the buffer is pinned in the aperture. Currently we count the fenced as pinned if the buffer has already been seen in the execbuffer. This leads to a false accounting of available fence registers, causing frequent mass evictions. Worse, if coupled with the change to make i915_gem_object_get_fence() report EDADLK upon fence starvation, the batchbuffer can fail with only one fence required... Fixes intel-gpu-tools/tests/gem_fenced_exec_thrash Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38735 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Tested-by: Paul Neumann <paul104x@yahoo.de> [danvet: Resolve the functional conflict with Jesse Barnes sprite patches, acked by Chris Wilson on irc.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ff3066c4c76a..c78930ed2e80 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2435,6 +2435,8 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
2435 2435
2436 if (obj->fence_reg != I915_FENCE_REG_NONE) { 2436 if (obj->fence_reg != I915_FENCE_REG_NONE) {
2437 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 2437 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
2438
2439 WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count);
2438 i915_gem_clear_fence_reg(obj->base.dev, 2440 i915_gem_clear_fence_reg(obj->base.dev,
2439 &dev_priv->fence_regs[obj->fence_reg]); 2441 &dev_priv->fence_regs[obj->fence_reg]);
2440 2442
@@ -2459,7 +2461,7 @@ i915_find_fence_reg(struct drm_device *dev,
2459 if (!reg->obj) 2461 if (!reg->obj)
2460 return reg; 2462 return reg;
2461 2463
2462 if (!reg->obj->pin_count) 2464 if (!reg->pin_count)
2463 avail = reg; 2465 avail = reg;
2464 } 2466 }
2465 2467
@@ -2469,7 +2471,7 @@ i915_find_fence_reg(struct drm_device *dev,
2469 /* None available, try to steal one or wait for a user to finish */ 2471 /* None available, try to steal one or wait for a user to finish */
2470 avail = first = NULL; 2472 avail = first = NULL;
2471 list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { 2473 list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) {
2472 if (reg->obj->pin_count) 2474 if (reg->pin_count)
2473 continue; 2475 continue;
2474 2476
2475 if (first == NULL) 2477 if (first == NULL)
@@ -2664,6 +2666,7 @@ i915_gem_clear_fence_reg(struct drm_device *dev,
2664 list_del_init(&reg->lru_list); 2666 list_del_init(&reg->lru_list);
2665 reg->obj = NULL; 2667 reg->obj = NULL;
2666 reg->setup_seqno = 0; 2668 reg->setup_seqno = 0;
2669 reg->pin_count = 0;
2667} 2670}
2668 2671
2669/** 2672/**