| From ab7bc74d70e58ff6f07227bf0e5b605bc71a19b4 Mon Sep 17 00:00:00 2001 |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Date: Wed, 24 Jul 2013 23:25:03 +0200 |
| Subject: drm/i915: fix reference counting in i915_gem_create |
| |
| This function is called without the dev->struct_mutex held, hence we |
| need to use the _unlocked unreference variants. |
| |
| As soon as the object is registered userspace can sneak in here with a |
| gem_close ioctl call, so the object can (and with my new evil tests |
| actually does) get the final unreference in this place. The lack of |
| locking then results in hilarity and some good leakage. |
| |
| To fix this we simply need to revert |
| |
| Chris Wilson <chris@chris-wilson.co.uk> |
| |
| v2: We need to make the trace call _before_ we drop our ref - the |
| object might very well be gone by then already. |
| |
| v3: Just revert the original patch as suggested by Chris Wilson. |
| |
| Cc: Chris Wilson <chris@chris-wilson.co.uk> |
| Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> |
| [danvet: Remove the added white line again to tighten the return |
| block, requested by Chris.] |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| |
| (cherry picked from commit d861e3387650296f1fca2a4dd0dcd380c8fdddad) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/i915_gem.c | 14 +++++--------- |
| 1 file changed, 5 insertions(+), 9 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c |
| index 6703fc35a0b9..050eb9b92595 100644 |
| --- a/drivers/gpu/drm/i915/i915_gem.c |
| +++ b/drivers/gpu/drm/i915/i915_gem.c |
| @@ -219,16 +219,10 @@ i915_gem_create(struct drm_file *file, |
| return -ENOMEM; |
| |
| ret = drm_gem_handle_create(file, &obj->base, &handle); |
| - if (ret) { |
| - drm_gem_object_release(&obj->base); |
| - i915_gem_info_remove_obj(dev->dev_private, obj->base.size); |
| - i915_gem_object_free(obj); |
| - return ret; |
| - } |
| - |
| /* drop reference from allocate - handle holds it now */ |
| - drm_gem_object_unreference(&obj->base); |
| - trace_i915_gem_object_create(obj); |
| + drm_gem_object_unreference_unlocked(&obj->base); |
| + if (ret) |
| + return ret; |
| |
| *handle_p = handle; |
| return 0; |
| @@ -3942,6 +3936,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, |
| } else |
| obj->cache_level = I915_CACHE_NONE; |
| |
| + trace_i915_gem_object_create(obj); |
| + |
| return obj; |
| } |
| |
| -- |
| 1.8.5.rc3 |
| |