diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-02-11 14:26:28 +0000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-02-20 12:21:10 +1000 |
commit | 8d59bae5d9aae10ab230561519bfb97962509bcb (patch) | |
tree | 0be3a5e9cbb512e6ec933a8e74f59958c7ee8018 | |
parent | a35f2e2b83a789e189a501ebd722bc9a1310eb05 (diff) | |
download | op-kernel-dev-8d59bae5d9aae10ab230561519bfb97962509bcb.zip op-kernel-dev-8d59bae5d9aae10ab230561519bfb97962509bcb.tar.gz |
drm: Do not leak a new reference for flink() on an existing name
The name table should only hold a single reference, so avoid leaking
additional references for secondary calls to flink().
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@linux.ie>
-rw-r--r-- | drivers/gpu/drm/drm_gem.c | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index e5a8ebf..5dad6b9 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -301,27 +301,25 @@ again: } spin_lock(&dev->object_name_lock); - if (obj->name) { - args->name = obj->name; + if (!obj->name) { + ret = idr_get_new_above(&dev->object_name_idr, obj, 1, + &obj->name); + args->name = (uint64_t) obj->name; spin_unlock(&dev->object_name_lock); - return 0; - } - ret = idr_get_new_above(&dev->object_name_idr, obj, 1, - &obj->name); - spin_unlock(&dev->object_name_lock); - if (ret == -EAGAIN) - goto again; - if (ret != 0) - goto err; + if (ret == -EAGAIN) + goto again; - /* - * Leave the reference from the lookup around as the - * name table now holds one - */ - args->name = (uint64_t) obj->name; + if (ret != 0) + goto err; - return 0; + /* Allocate a reference for the name table. */ + drm_gem_object_reference(obj); + } else { + args->name = (uint64_t) obj->name; + spin_unlock(&dev->object_name_lock); + ret = 0; + } err: mutex_lock(&dev->struct_mutex); @@ -452,6 +450,7 @@ drm_gem_object_handle_free(struct kref *kref) spin_lock(&dev->object_name_lock); if (obj->name) { idr_remove(&dev->object_name_idr, obj->name); + obj->name = 0; spin_unlock(&dev->object_name_lock); /* * The object name held a reference to this object, drop |