Rev 3298 | Rev 4075 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3298 | Rev 3480 | ||
---|---|---|---|
Line 215... | Line 215... | ||
215 | * could race us to double-decrement the refcount and cause a |
215 | * could race us to double-decrement the refcount and cause a |
216 | * use-after-free later. Given the frequency of our handle lookups, |
216 | * use-after-free later. Given the frequency of our handle lookups, |
217 | * we may want to use ida for number allocation and a hash table |
217 | * we may want to use ida for number allocation and a hash table |
218 | * for the pointers, anyway. |
218 | * for the pointers, anyway. |
219 | */ |
219 | */ |
- | 220 | if(handle == -2) |
|
- | 221 | printf("%s handle %d\n", __FUNCTION__, handle); |
|
- | 222 | ||
220 | spin_lock(&filp->table_lock); |
223 | spin_lock(&filp->table_lock); |
Line 221... | Line 224... | ||
221 | 224 | ||
222 | /* Check if we currently have a reference on the object */ |
225 | /* Check if we currently have a reference on the object */ |
223 | obj = idr_find(&filp->object_idr, handle); |
226 | obj = idr_find(&filp->object_idr, handle); |
Line 255... | Line 258... | ||
255 | { |
258 | { |
256 | struct drm_device *dev = obj->dev; |
259 | struct drm_device *dev = obj->dev; |
257 | int ret; |
260 | int ret; |
Line 258... | Line 261... | ||
258 | 261 | ||
259 | /* |
262 | /* |
- | 263 | * Get the user-visible handle using idr. Preload and perform |
|
260 | * Get the user-visible handle using idr. |
264 | * allocation under our spinlock. |
261 | */ |
- | |
262 | again: |
- | |
263 | /* ensure there is space available to allocate a handle */ |
265 | */ |
264 | if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0) |
- | |
265 | return -ENOMEM; |
- | |
266 | - | ||
267 | /* do the allocation under our spinlock */ |
266 | idr_preload(GFP_KERNEL); |
- | 267 | spin_lock(&file_priv->table_lock); |
|
268 | spin_lock(&file_priv->table_lock); |
268 | |
- | 269 | ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT); |
|
269 | ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep); |
270 | |
270 | spin_unlock(&file_priv->table_lock); |
271 | spin_unlock(&file_priv->table_lock); |
271 | if (ret == -EAGAIN) |
- | |
272 | goto again; |
272 | idr_preload_end(); |
273 | else if (ret) |
273 | if (ret < 0) |
- | 274 | return ret; |
|
Line 274... | Line 275... | ||
274 | return ret; |
275 | *handlep = ret; |
Line 275... | Line 276... | ||
275 | 276 | ||
276 | drm_gem_object_handle_reference(obj); |
277 | drm_gem_object_handle_reference(obj); |
Line 382... | Line 383... | ||
382 | drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, |
383 | drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, |
383 | u32 handle) |
384 | u32 handle) |
384 | { |
385 | { |
385 | struct drm_gem_object *obj; |
386 | struct drm_gem_object *obj; |
Line -... | Line 387... | ||
- | 387 | ||
- | 388 | if(handle == -2) |
|
- | 389 | printf("%s handle %d\n", __FUNCTION__, handle); |
|
386 | 390 | ||
Line 387... | Line 391... | ||
387 | spin_lock(&filp->table_lock); |
391 | spin_lock(&filp->table_lock); |
388 | 392 | ||
389 | /* Check if we currently have a reference on the object */ |
393 | /* Check if we currently have a reference on the object */ |
Line 437... | Line 441... | ||
437 | 441 | ||
438 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
442 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
439 | if (obj == NULL) |
443 | if (obj == NULL) |
Line 440... | Line -... | ||
440 | return -ENOENT; |
- | |
441 | 444 | return -ENOENT; |
|
442 | again: |
- | |
443 | if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { |
- | |
444 | ret = -ENOMEM; |
- | |
445 | goto err; |
- | |
446 | } |
445 | |
447 | 446 | idr_preload(GFP_KERNEL); |
|
448 | spin_lock(&dev->object_name_lock); |
447 | spin_lock(&dev->object_name_lock); |
449 | if (!obj->name) { |
448 | if (!obj->name) { |
450 | ret = idr_get_new_above(&dev->object_name_idr, obj, 1, |
449 | ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT); |
451 | &obj->name); |
450 | obj->name = ret; |
- | 451 | args->name = (uint64_t) obj->name; |
|
Line 452... | Line 452... | ||
452 | args->name = (uint64_t) obj->name; |
452 | spin_unlock(&dev->object_name_lock); |
453 | spin_unlock(&dev->object_name_lock); |
- | |
454 | - | ||
455 | if (ret == -EAGAIN) |
453 | idr_preload_end(); |
- | 454 | ||
Line 456... | Line 455... | ||
456 | goto again; |
455 | if (ret < 0) |
457 | else if (ret) |
456 | goto err; |
458 | goto err; |
457 | ret = 0; |
459 | 458 | ||
460 | /* Allocate a reference for the name table. */ |
459 | /* Allocate a reference for the name table. */ |
- | 460 | drm_gem_object_reference(obj); |
|
461 | drm_gem_object_reference(obj); |
461 | } else { |
462 | } else { |
462 | args->name = (uint64_t) obj->name; |
Line 463... | Line 463... | ||
463 | args->name = (uint64_t) obj->name; |
463 | spin_unlock(&dev->object_name_lock); |
464 | spin_unlock(&dev->object_name_lock); |
464 | idr_preload_end(); |
Line 486... | Line 486... | ||
486 | u32 handle; |
486 | u32 handle; |
Line 487... | Line 487... | ||
487 | 487 | ||
488 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
488 | if (!(dev->driver->driver_features & DRIVER_GEM)) |
Line -... | Line 489... | ||
- | 489 | return -ENODEV; |
|
- | 490 | ||
- | 491 | if(handle == -2) |
|
489 | return -ENODEV; |
492 | printf("%s handle %d\n", __FUNCTION__, handle); |
490 | 493 | ||
491 | spin_lock(&dev->object_name_lock); |
494 | spin_lock(&dev->object_name_lock); |
492 | obj = idr_find(&dev->object_name_idr, (int) args->name); |
495 | obj = idr_find(&dev->object_name_idr, (int) args->name); |
493 | if (obj) |
496 | if (obj) |
Line 547... | Line 550... | ||
547 | void |
550 | void |
548 | drm_gem_release(struct drm_device *dev, struct drm_file *file_private) |
551 | drm_gem_release(struct drm_device *dev, struct drm_file *file_private) |
549 | { |
552 | { |
550 | idr_for_each(&file_private->object_idr, |
553 | idr_for_each(&file_private->object_idr, |
551 | &drm_gem_object_release_handle, file_private); |
554 | &drm_gem_object_release_handle, file_private); |
552 | - | ||
553 | idr_remove_all(&file_private->object_idr); |
- | |
554 | idr_destroy(&file_private->object_idr); |
555 | idr_destroy(&file_private->object_idr); |
555 | } |
556 | } |
556 | #endif |
557 | #endif |
Line 557... | Line 558... | ||
557 | 558 |