drm/i915: Return error from i915_gem_object_get_fence_reg() when failing.

Previously, the caller would continue along without knowing that the
function failed, resulting in potential mis-rendering.  Right now vm_fault
just returns SIGBUS in that case, and we may need to disable signal handling
to avoid that happening.

Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
Eric Anholt 2009-01-27 10:33:49 -08:00 committed by Dave Airlie
parent ab657db12d
commit d9ddcb96e0

View File

@ -52,7 +52,7 @@ static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
unsigned alignment); unsigned alignment);
static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj); static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
static int i915_gem_evict_something(struct drm_device *dev); static int i915_gem_evict_something(struct drm_device *dev);
static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
@ -585,8 +585,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
/* Need a new fence register? */ /* Need a new fence register? */
if (obj_priv->fence_reg == I915_FENCE_REG_NONE && if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
obj_priv->tiling_mode != I915_TILING_NONE) obj_priv->tiling_mode != I915_TILING_NONE) {
i915_gem_object_get_fence_reg(obj); ret = i915_gem_object_get_fence_reg(obj);
if (ret != 0)
return VM_FAULT_SIGBUS;
}
pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
page_offset; page_offset;
@ -1513,7 +1516,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
* It then sets up the reg based on the object's properties: address, pitch * It then sets up the reg based on the object's properties: address, pitch
* and tiling format. * and tiling format.
*/ */
static void static int
i915_gem_object_get_fence_reg(struct drm_gem_object *obj) i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
{ {
struct drm_device *dev = obj->dev; struct drm_device *dev = obj->dev;
@ -1563,10 +1566,11 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
* objects to finish before trying again. * objects to finish before trying again.
*/ */
if (i == dev_priv->num_fence_regs) { if (i == dev_priv->num_fence_regs) {
ret = i915_gem_object_wait_rendering(reg->obj); ret = i915_gem_object_set_to_gtt_domain(reg->obj, 0);
if (ret) { if (ret) {
WARN(ret, "wait_rendering failed: %d\n", ret); WARN(ret != -ERESTARTSYS,
return; "switch to GTT domain failed: %d\n", ret);
return ret;
} }
goto try_again; goto try_again;
} }
@ -1591,6 +1595,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
i915_write_fence_reg(reg); i915_write_fence_reg(reg);
else else
i830_write_fence_reg(reg); i830_write_fence_reg(reg);
return 0;
} }
/** /**