diff options
author | Dave Airlie <airlied@redhat.com> | 2010-09-27 02:17:17 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-09-30 19:17:44 -0400 |
commit | 29d08b3efddca628b0360411ab2b85f7b1723f48 (patch) | |
tree | f89a8a3069ebe9828b8a08c4b123f52625bf0bc7 /drivers/gpu/drm/radeon | |
parent | 130b9851933e6da636502cd85e1ba8f45f862e8c (diff) |
drm/gem: handlecount isn't really a kref so don't make it one.
There were lots of places being inconsistent since handle count
looked like a kref but it really wasn't.
Fix this my just making handle count an atomic on the object,
and have it increase the normal object kref.
Now i915/radeon/nouveau drivers can drop the normal reference on
userspace object creation, and have the handle hold it.
This patch fixes a memory leak or corruption on unload, because
the driver had no way of knowing if a handle had been actually
added for this object, and the fbcon object needed to know this
to clean itself up properly.
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 4 |
3 files changed, 8 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7422f274615a..b92d2f2fcbed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -843,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
843 | { | 843 | { |
844 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); | 844 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
845 | 845 | ||
846 | if (radeon_fb->obj) | 846 | if (radeon_fb->obj) { |
847 | drm_gem_object_unreference_unlocked(radeon_fb->obj); | 847 | drm_gem_object_unreference_unlocked(radeon_fb->obj); |
848 | } | ||
848 | drm_framebuffer_cleanup(fb); | 849 | drm_framebuffer_cleanup(fb); |
849 | kfree(radeon_fb); | 850 | kfree(radeon_fb); |
850 | } | 851 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index c74a8b20d941..9cdf6a35bc2c 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -94,8 +94,10 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) | |||
94 | ret = radeon_bo_reserve(rbo, false); | 94 | ret = radeon_bo_reserve(rbo, false); |
95 | if (likely(ret == 0)) { | 95 | if (likely(ret == 0)) { |
96 | radeon_bo_kunmap(rbo); | 96 | radeon_bo_kunmap(rbo); |
97 | radeon_bo_unpin(rbo); | ||
97 | radeon_bo_unreserve(rbo); | 98 | radeon_bo_unreserve(rbo); |
98 | } | 99 | } |
100 | drm_gem_object_handle_unreference(gobj); | ||
99 | drm_gem_object_unreference_unlocked(gobj); | 101 | drm_gem_object_unreference_unlocked(gobj); |
100 | } | 102 | } |
101 | 103 | ||
@@ -325,8 +327,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
325 | { | 327 | { |
326 | struct fb_info *info; | 328 | struct fb_info *info; |
327 | struct radeon_framebuffer *rfb = &rfbdev->rfb; | 329 | struct radeon_framebuffer *rfb = &rfbdev->rfb; |
328 | struct radeon_bo *rbo; | ||
329 | int r; | ||
330 | 330 | ||
331 | if (rfbdev->helper.fbdev) { | 331 | if (rfbdev->helper.fbdev) { |
332 | info = rfbdev->helper.fbdev; | 332 | info = rfbdev->helper.fbdev; |
@@ -338,14 +338,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
338 | } | 338 | } |
339 | 339 | ||
340 | if (rfb->obj) { | 340 | if (rfb->obj) { |
341 | rbo = rfb->obj->driver_private; | 341 | radeonfb_destroy_pinned_object(rfb->obj); |
342 | r = radeon_bo_reserve(rbo, false); | 342 | rfb->obj = NULL; |
343 | if (likely(r == 0)) { | ||
344 | radeon_bo_kunmap(rbo); | ||
345 | radeon_bo_unpin(rbo); | ||
346 | radeon_bo_unreserve(rbo); | ||
347 | } | ||
348 | drm_gem_object_unreference_unlocked(rfb->obj); | ||
349 | } | 343 | } |
350 | drm_fb_helper_fini(&rfbdev->helper); | 344 | drm_fb_helper_fini(&rfbdev->helper); |
351 | drm_framebuffer_cleanup(&rfb->base); | 345 | drm_framebuffer_cleanup(&rfb->base); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c578f265b24c..d1e595d91723 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
201 | return r; | 201 | return r; |
202 | } | 202 | } |
203 | r = drm_gem_handle_create(filp, gobj, &handle); | 203 | r = drm_gem_handle_create(filp, gobj, &handle); |
204 | /* drop reference from allocate - handle holds it now */ | ||
205 | drm_gem_object_unreference_unlocked(gobj); | ||
204 | if (r) { | 206 | if (r) { |
205 | drm_gem_object_unreference_unlocked(gobj); | ||
206 | return r; | 207 | return r; |
207 | } | 208 | } |
208 | drm_gem_object_handle_unreference_unlocked(gobj); | ||
209 | args->handle = handle; | 209 | args->handle = handle; |
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |