From 7b1f36400747c8e20c2956d610688a31540b97ce Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Thu, 15 May 2008 17:33:50 +0800 Subject: [PATCH] modeset: fix fb->bo usage count We should increase the usage count of bo when assigning it to fb, and decrease it when destroying fb. Otherwise, fb may refer to a already freed bo. --- linux-core/drm_crtc.c | 10 +++++++--- linux-core/intel_fb.c | 1 - 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 62755b7..04f012d 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -226,6 +226,7 @@ void drm_framebuffer_destroy(struct drm_framebuffer *fb) drm_idr_put(dev, fb->id); list_del(&fb->head); dev->mode_config.num_fb--; + drm_bo_usage_deref_unlocked(&fb->bo); kfree(fb); } @@ -871,7 +872,7 @@ static int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_objec { struct drm_user_object *uo; struct drm_hash_item *hash; - int ret; + int ret = 0; *bo = NULL; @@ -890,7 +891,7 @@ static int drm_get_buffer_object(struct drm_device *dev, struct drm_buffer_objec } *bo = drm_user_object_entry(uo, struct drm_buffer_object, base); - ret = 0; + atomic_inc(&(*bo)->usage); out_err: mutex_unlock(&dev->struct_mutex); return ret; @@ -1797,10 +1798,11 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, } else { DRM_ERROR("crtc does not support cursor\n"); ret = -EFAULT; - goto out; } } out: + if (bo) + drm_bo_usage_deref_unlocked(&bo); mutex_unlock(&dev->mode_config.mutex); return ret; } @@ -1855,6 +1857,7 @@ int drm_mode_addfb(struct drm_device *dev, fb = drm_framebuffer_create(dev); if (!fb) { DRM_ERROR("could not create framebuffer\n"); + drm_bo_usage_deref_unlocked(&bo); ret = -EINVAL; goto out; } @@ -2572,6 +2575,7 @@ int drm_mode_replacefb(struct drm_device *dev, fb->pitch = r->pitch; fb->bits_per_pixel = r->bpp; fb->depth = r->depth; + drm_bo_usage_deref_unlocked(&fb->bo); fb->bo = bo; /* find all crtcs connected to this fb */ diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 9934e3a..4f941a1 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -779,7 +779,6 @@ int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) if (info) { unregister_framebuffer(info); drm_bo_kunmap(&fb->kmap); - drm_bo_usage_deref_unlocked(&fb->bo); drm_framebuffer_destroy(fb); framebuffer_release(info); } -- 1.5.4.1