From baa2e8f526786f677594d814ad45428029951ec1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 13 Dec 2012 10:28:38 +0000 Subject: [PATCH] drm/i915: Keep the reserved objects pinned whilst we perform relocations A theory, at last. In the process of performing the relocations, we may have to jostle the objects around into the GTT, perturbing the existing execbuffer objects - thus fouling up any earlier reloctions. In order to make sure that is impossible, make sure we keep the reserved objects pinned until after the relocation processing. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 30 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index ee8f97f..561c4bd 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -485,6 +485,8 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, goto err; } + return 0; + err: /* Decrement pin count for bound objects */ list_for_each_entry(obj, objects, exec_list) i915_gem_execbuffer_unreserve_object(obj); @@ -498,6 +500,15 @@ err: /* Decrement pin count for bound objects */ } while (1); } +static void +i915_gem_execbuffer_unreserve(struct list_head *objects) +{ + struct drm_i915_gem_object *obj; + + list_for_each_entry(obj, objects, exec_list) + i915_gem_execbuffer_unreserve_object(obj); +} + static int i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_file *file, @@ -961,17 +972,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, /* The objects are in their final locations, apply the relocations. */ ret = i915_gem_execbuffer_relocate(dev, eb, &objects); - if (ret) { - if (ret == -EFAULT) { - ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, - &objects, eb, - exec, - args->buffer_count); - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - } - if (ret) - goto err; + if (ret == -EFAULT) { + ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, + &objects, eb, + exec, + args->buffer_count); + BUG_ON(!mutex_is_locked(&dev->struct_mutex)); } + i915_gem_execbuffer_unreserve(&objects); + if (ret) + goto err; /* Set the pending read domains for the batch buffer to COMMAND */ if (batch_obj->base.pending_write_domain) { -- 1.7.10.4