diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-02-11 09:26:46 -0500 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-03-10 23:32:13 -0400 |
commit | fc7170ba281c041852eeda52d4faf5db720c99ce (patch) | |
tree | 4c846b70753cce867593adfd34df6925938108e6 | |
parent | 22c344e9a03beeb7071a588a973012749f84a830 (diff) |
drm/i915: Check to see if we've pinned all available fences
We need to check and report if there are no available fences - or else we
spin endlessly waiting for a buffer to magically unpin itself.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 12c7d78d9240..2b5c7ad9e64a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1557,7 +1557,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) | |||
1557 | struct drm_i915_private *dev_priv = dev->dev_private; | 1557 | struct drm_i915_private *dev_priv = dev->dev_private; |
1558 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1558 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
1559 | struct drm_i915_fence_reg *reg = NULL; | 1559 | struct drm_i915_fence_reg *reg = NULL; |
1560 | int i, ret; | 1560 | struct drm_i915_gem_object *old_obj_priv = NULL; |
1561 | int i, ret, avail; | ||
1561 | 1562 | ||
1562 | switch (obj_priv->tiling_mode) { | 1563 | switch (obj_priv->tiling_mode) { |
1563 | case I915_TILING_NONE: | 1564 | case I915_TILING_NONE: |
@@ -1581,17 +1582,24 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) | |||
1581 | 1582 | ||
1582 | /* First try to find a free reg */ | 1583 | /* First try to find a free reg */ |
1583 | try_again: | 1584 | try_again: |
1585 | avail = 0; | ||
1584 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { | 1586 | for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { |
1585 | reg = &dev_priv->fence_regs[i]; | 1587 | reg = &dev_priv->fence_regs[i]; |
1586 | if (!reg->obj) | 1588 | if (!reg->obj) |
1587 | break; | 1589 | break; |
1590 | |||
1591 | old_obj_priv = reg->obj->driver_private; | ||
1592 | if (!old_obj_priv->pin_count) | ||
1593 | avail++; | ||
1588 | } | 1594 | } |
1589 | 1595 | ||
1590 | /* None available, try to steal one or wait for a user to finish */ | 1596 | /* None available, try to steal one or wait for a user to finish */ |
1591 | if (i == dev_priv->num_fence_regs) { | 1597 | if (i == dev_priv->num_fence_regs) { |
1592 | struct drm_i915_gem_object *old_obj_priv = NULL; | ||
1593 | loff_t offset; | 1598 | loff_t offset; |
1594 | 1599 | ||
1600 | if (avail == 0) | ||
1601 | return -ENOMEM; | ||
1602 | |||
1595 | /* Could try to use LRU here instead... */ | 1603 | /* Could try to use LRU here instead... */ |
1596 | for (i = dev_priv->fence_reg_start; | 1604 | for (i = dev_priv->fence_reg_start; |
1597 | i < dev_priv->num_fence_regs; i++) { | 1605 | i < dev_priv->num_fence_regs; i++) { |