diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-02-11 09:26:28 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-02-19 21:21:10 -0500 |
commit | 8d59bae5d9aae10ab230561519bfb97962509bcb (patch) | |
tree | 0be3a5e9cbb512e6ec933a8e74f59958c7ee8018 /drivers | |
parent | a35f2e2b83a789e189a501ebd722bc9a1310eb05 (diff) |
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>
Diffstat (limited to 'drivers')
-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 e5a8ebf9a662..5dad6b9d0dec 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -301,27 +301,25 @@ again: | |||
301 | } | 301 | } |
302 | 302 | ||
303 | spin_lock(&dev->object_name_lock); | 303 | spin_lock(&dev->object_name_lock); |
304 | if (obj->name) { | 304 | if (!obj->name) { |
305 | args->name = obj->name; | 305 | ret = idr_get_new_above(&dev->object_name_idr, obj, 1, |
306 | &obj->name); | ||
307 | args->name = (uint64_t) obj->name; | ||
306 | spin_unlock(&dev->object_name_lock); | 308 | spin_unlock(&dev->object_name_lock); |
307 | return 0; | ||
308 | } | ||
309 | ret = idr_get_new_above(&dev->object_name_idr, obj, 1, | ||
310 | &obj->name); | ||
311 | spin_unlock(&dev->object_name_lock); | ||
312 | if (ret == -EAGAIN) | ||
313 | goto again; | ||
314 | 309 | ||
315 | if (ret != 0) | 310 | if (ret == -EAGAIN) |
316 | goto err; | 311 | goto again; |
317 | 312 | ||
318 | /* | 313 | if (ret != 0) |
319 | * Leave the reference from the lookup around as the | 314 | goto err; |
320 | * name table now holds one | ||
321 | */ | ||
322 | args->name = (uint64_t) obj->name; | ||
323 | 315 | ||
324 | return 0; | 316 | /* Allocate a reference for the name table. */ |
317 | drm_gem_object_reference(obj); | ||
318 | } else { | ||
319 | args->name = (uint64_t) obj->name; | ||
320 | spin_unlock(&dev->object_name_lock); | ||
321 | ret = 0; | ||
322 | } | ||
325 | 323 | ||
326 | err: | 324 | err: |
327 | mutex_lock(&dev->struct_mutex); | 325 | mutex_lock(&dev->struct_mutex); |
@@ -452,6 +450,7 @@ drm_gem_object_handle_free(struct kref *kref) | |||
452 | spin_lock(&dev->object_name_lock); | 450 | spin_lock(&dev->object_name_lock); |
453 | if (obj->name) { | 451 | if (obj->name) { |
454 | idr_remove(&dev->object_name_idr, obj->name); | 452 | idr_remove(&dev->object_name_idr, obj->name); |
453 | obj->name = 0; | ||
455 | spin_unlock(&dev->object_name_lock); | 454 | spin_unlock(&dev->object_name_lock); |
456 | /* | 455 | /* |
457 | * The object name held a reference to this object, drop | 456 | * The object name held a reference to this object, drop |