summaryrefslogtreecommitdiff
path: root/linux-core/drm_gem.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-01 20:12:39 -0700
committerKeith Packard <keithp@keithp.com>2008-05-01 20:12:39 -0700
commitabc896638fdcd8ccb457ad7b43dbe7ad229ba501 (patch)
tree157a7961a250a9e443ef4a1e9a89320ecab8990b /linux-core/drm_gem.c
parentc10695bb7ab44494badc21c822eac3140cf4e117 (diff)
Use krefs for refcounting.
krefs are way easier than a custom-coded spinlock+int combo.
Diffstat (limited to 'linux-core/drm_gem.c')
-rw-r--r--linux-core/drm_gem.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c
index ee3dbe47..d39585e9 100644
--- a/linux-core/drm_gem.c
+++ b/linux-core/drm_gem.c
@@ -73,13 +73,14 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
+ obj->dev = dev;
obj->filp = shmem_file_setup("drm mm object", size, 0);
if (IS_ERR(obj->filp)) {
kfree(obj);
return NULL;
}
- obj->refcount = 1;
+ kref_init (&obj->refcount);
obj->size = size;
if (dev->driver->gem_init_object != NULL &&
@@ -352,27 +353,29 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
void
drm_gem_object_reference(struct drm_device *dev, struct drm_gem_object *obj)
{
- spin_lock(&obj->lock);
- obj->refcount++;
- spin_unlock(&obj->lock);
+ kref_get(&obj->refcount);
}
EXPORT_SYMBOL(drm_gem_object_reference);
+static void
+drm_gem_object_free (struct kref *kref)
+{
+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
+ struct drm_device *dev = obj->dev;
+
+ if (dev->driver->gem_free_object != NULL)
+ dev->driver->gem_free_object(dev, obj);
+
+ fput(obj->filp);
+ kfree(obj);
+}
+
void
drm_gem_object_unreference(struct drm_device *dev, struct drm_gem_object *obj)
{
if (obj == NULL)
return;
- spin_lock(&obj->lock);
- obj->refcount--;
- spin_unlock(&obj->lock);
- if (obj->refcount == 0) {
- if (dev->driver->gem_free_object != NULL)
- dev->driver->gem_free_object(dev, obj);
-
- fput(obj->filp);
- kfree(obj);
- }
+ kref_put (&obj->refcount, drm_gem_object_free);
}
EXPORT_SYMBOL(drm_gem_object_unreference);