Rev 6935 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6935 | Rev 6937 | ||
---|---|---|---|
Line 168... | Line 168... | ||
168 | obj->size = size; |
168 | obj->size = size; |
169 | drm_vma_node_reset(&obj->vma_node); |
169 | drm_vma_node_reset(&obj->vma_node); |
170 | } |
170 | } |
171 | EXPORT_SYMBOL(drm_gem_private_object_init); |
171 | EXPORT_SYMBOL(drm_gem_private_object_init); |
Line -... | Line 172... | ||
- | 172 | ||
- | 173 | static void |
|
- | 174 | drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) |
|
- | 175 | { |
|
- | 176 | /* |
|
- | 177 | * Note: obj->dma_buf can't disappear as long as we still hold a |
|
- | 178 | * handle reference in obj->handle_count. |
|
- | 179 | */ |
|
- | 180 | } |
|
172 | 181 | ||
173 | /** |
182 | /** |
174 | * drm_gem_object_handle_free - release resources bound to userspace handles |
183 | * drm_gem_object_handle_free - release resources bound to userspace handles |
175 | * @obj: GEM object to clean up. |
184 | * @obj: GEM object to clean up. |
176 | * |
185 | * |
Line 193... | Line 202... | ||
193 | 202 | ||
194 | 203 | ||
195 | static void |
204 | static void |
- | 205 | drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) |
|
- | 206 | { |
|
- | 207 | struct drm_device *dev = obj->dev; |
|
196 | drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) |
208 | bool final = false; |
197 | { |
209 | |
Line 198... | Line 210... | ||
198 | if (WARN_ON(obj->handle_count == 0)) |
210 | if (WARN_ON(obj->handle_count == 0)) |
199 | return; |
211 | return; |
200 | 212 | ||
201 | /* |
213 | /* |
202 | * Must bump handle count first as this may be the last |
214 | * Must bump handle count first as this may be the last |
Line 203... | Line 215... | ||
203 | * ref, in which case the object would disappear before we |
215 | * ref, in which case the object would disappear before we |
204 | * checked for a name |
216 | * checked for a name |
205 | */ |
217 | */ |
- | 218 | ||
206 | 219 | mutex_lock(&dev->object_name_lock); |
|
207 | mutex_lock(&obj->dev->object_name_lock); |
220 | if (--obj->handle_count == 0) { |
Line -... | Line 221... | ||
- | 221 | drm_gem_object_handle_free(obj); |
|
208 | if (--obj->handle_count == 0) { |
222 | final = true; |
209 | drm_gem_object_handle_free(obj); |
223 | } |
Line -... | Line 224... | ||
- | 224 | mutex_unlock(&dev->object_name_lock); |
|
- | 225 | ||
- | 226 | if (final) |
|
- | 227 | drm_gem_object_unreference_unlocked(obj); |
|
- | 228 | } |
|
- | 229 | ||
- | 230 | /* |
|
- | 231 | * Called at device or object close to release the file's |
|
- | 232 | * handle references on objects. |
|
- | 233 | */ |
|
- | 234 | static int |
|
- | 235 | drm_gem_object_release_handle(int id, void *ptr, void *data) |
|
- | 236 | { |
|
- | 237 | struct drm_file *file_priv = data; |
|
- | 238 | struct drm_gem_object *obj = ptr; |
|
- | 239 | struct drm_device *dev = obj->dev; |
|
- | 240 | ||
- | 241 | if (drm_core_check_feature(dev, DRIVER_PRIME)) |
|
- | 242 | drm_gem_remove_prime_handles(obj, file_priv); |
|
- | 243 | // drm_vma_node_revoke(&obj->vma_node, file_priv->filp); |
|
- | 244 | ||
- | 245 | if (dev->driver->gem_close_object) |
|
- | 246 | dev->driver->gem_close_object(obj, file_priv); |
|
210 | } |
247 | |
211 | mutex_unlock(&obj->dev->object_name_lock); |
248 | drm_gem_object_handle_unreference_unlocked(obj); |
212 | 249 | ||
213 | drm_gem_object_unreference_unlocked(obj); |
250 | return 0; |
214 | } |
251 | } |
215 | 252 | ||
- | 253 | /** |
|
216 | /** |
254 | * drm_gem_handle_delete - deletes the given file-private handle |
217 | * drm_gem_handle_delete - deletes the given file-private handle |
255 | * @filp: drm file-private structure to use for the handle look up |
218 | * @filp: drm file-private structure to use for the handle look up |
256 | * @handle: userspace handle to delete |
219 | * @handle: userspace handle to delete |
257 | * |
220 | * |
258 | * Removes the GEM handle from the @filp lookup table which has been added with |
221 | * Removes the GEM handle from the @filp lookup table and if this is the last |
259 | * drm_gem_handle_create(). If this is the last handle also cleans up linked |
Line 248... | Line 286... | ||
248 | 286 | ||
249 | /* Release reference and decrement refcount. */ |
287 | /* Release reference and decrement refcount. */ |
250 | idr_remove(&filp->object_idr, handle); |
288 | idr_remove(&filp->object_idr, handle); |
Line 251... | Line -... | ||
251 | spin_unlock(&filp->table_lock); |
- | |
252 | - | ||
253 | // drm_vma_node_revoke(&obj->vma_node, filp->filp); |
- | |
254 | - | ||
255 | if (dev->driver->gem_close_object) |
- | |
256 | dev->driver->gem_close_object(obj, filp); |
289 | spin_unlock(&filp->table_lock); |
257 | 290 | ||
258 | drm_gem_object_handle_unreference_unlocked(obj); |
291 | drm_gem_object_release_handle(handle, obj, filp); |
259 | return 0; |
292 | return 0; |
Line 260... | Line 293... | ||
260 | } |
293 | } |
Line 284... | Line 317... | ||
284 | * @handlep: pointer to return the created handle to the caller |
317 | * @handlep: pointer to return the created handle to the caller |
285 | * |
318 | * |
286 | * This expects the dev->object_name_lock to be held already and will drop it |
319 | * This expects the dev->object_name_lock to be held already and will drop it |
287 | * before returning. Used to avoid races in establishing new handles when |
320 | * before returning. Used to avoid races in establishing new handles when |
288 | * importing an object from either an flink name or a dma-buf. |
321 | * importing an object from either an flink name or a dma-buf. |
- | 322 | * |
|
- | 323 | * Handles must be release again through drm_gem_handle_delete(). This is done |
|
- | 324 | * when userspace closes @file_priv for all attached handles, or through the |
|
- | 325 | * GEM_CLOSE ioctl for individual handles. |
|
289 | */ |
326 | */ |
290 | int |
327 | int |
291 | drm_gem_handle_create_tail(struct drm_file *file_priv, |
328 | drm_gem_handle_create_tail(struct drm_file *file_priv, |
292 | struct drm_gem_object *obj, |
329 | struct drm_gem_object *obj, |
293 | u32 *handlep) |
330 | u32 *handlep) |
294 | { |
331 | { |
295 | struct drm_device *dev = obj->dev; |
332 | struct drm_device *dev = obj->dev; |
- | 333 | u32 handle; |
|
296 | int ret; |
334 | int ret; |
Line 297... | Line 335... | ||
297 | 335 | ||
- | 336 | WARN_ON(!mutex_is_locked(&dev->object_name_lock)); |
|
- | 337 | if (obj->handle_count++ == 0) |
|
Line 298... | Line 338... | ||
298 | WARN_ON(!mutex_is_locked(&dev->object_name_lock)); |
338 | drm_gem_object_reference(obj); |
299 | 339 | ||
300 | /* |
340 | /* |
301 | * Get the user-visible handle using idr. Preload and perform |
341 | * Get the user-visible handle using idr. Preload and perform |
302 | * allocation under our spinlock. |
342 | * allocation under our spinlock. |
303 | */ |
343 | */ |
Line 304... | Line 344... | ||
304 | idr_preload(GFP_KERNEL); |
344 | idr_preload(GFP_KERNEL); |
305 | spin_lock(&file_priv->table_lock); |
- | |
306 | - | ||
- | 345 | spin_lock(&file_priv->table_lock); |
|
307 | ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT); |
346 | |
308 | drm_gem_object_reference(obj); |
347 | ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT); |
- | 348 | ||
309 | obj->handle_count++; |
349 | spin_unlock(&file_priv->table_lock); |
310 | spin_unlock(&file_priv->table_lock); |
350 | idr_preload_end(); |
311 | idr_preload_end(); |
351 | |
Line 312... | Line 352... | ||
312 | mutex_unlock(&dev->object_name_lock); |
352 | mutex_unlock(&dev->object_name_lock); |
Line 313... | Line 353... | ||
313 | if (ret < 0) |
353 | if (ret < 0) |
314 | goto err_unref; |
354 | goto err_unref; |
315 | 355 | ||
316 | *handlep = ret; |
356 | handle = ret; |
Line 325... | Line 365... | ||
325 | ret = dev->driver->gem_open_object(obj, file_priv); |
365 | ret = dev->driver->gem_open_object(obj, file_priv); |
326 | if (ret) |
366 | if (ret) |
327 | goto err_revoke; |
367 | goto err_revoke; |
328 | } |
368 | } |
Line -... | Line 369... | ||
- | 369 | ||
329 | 370 | *handlep = handle; |
|
Line 330... | Line 371... | ||
330 | return 0; |
371 | return 0; |
331 | 372 | ||
332 | err_revoke: |
373 | err_revoke: |
333 | // drm_vma_node_revoke(&obj->vma_node, file_priv->filp); |
374 | // drm_vma_node_revoke(&obj->vma_node, file_priv->filp); |
334 | err_remove: |
375 | err_remove: |
335 | spin_lock(&file_priv->table_lock); |
376 | spin_lock(&file_priv->table_lock); |
336 | idr_remove(&file_priv->object_idr, *handlep); |
377 | idr_remove(&file_priv->object_idr, handle); |
337 | spin_unlock(&file_priv->table_lock); |
378 | spin_unlock(&file_priv->table_lock); |
338 | err_unref: |
379 | err_unref: |
339 | drm_gem_object_handle_unreference_unlocked(obj); |
380 | drm_gem_object_handle_unreference_unlocked(obj); |
Line 519... | Line 560... | ||
519 | drm_free_large(pages); |
560 | drm_free_large(pages); |
520 | } |
561 | } |
521 | EXPORT_SYMBOL(drm_gem_put_pages); |
562 | EXPORT_SYMBOL(drm_gem_put_pages); |
522 | #endif |
563 | #endif |
Line -... | Line 564... | ||
- | 564 | ||
- | 565 | /** |
|
- | 566 | * drm_gem_object_lookup - look up a GEM object from it's handle |
|
- | 567 | * @dev: DRM device |
|
- | 568 | * @filp: DRM file private date |
|
- | 569 | * @handle: userspace handle |
|
- | 570 | * |
|
- | 571 | * Returns: |
|
523 | 572 | * |
|
- | 573 | * A reference to the object named by the handle if such exists on @filp, NULL |
|
- | 574 | * otherwise. |
|
524 | /** Returns a reference to the object named by the handle. */ |
575 | */ |
525 | struct drm_gem_object * |
576 | struct drm_gem_object * |
526 | drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, |
577 | drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, |
527 | u32 handle) |
578 | u32 handle) |
528 | { |
579 | { |
Line 593... | Line 644... | ||
593 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
644 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
594 | if (obj == NULL) |
645 | if (obj == NULL) |
595 | return -ENOENT; |
646 | return -ENOENT; |
Line 596... | Line 647... | ||
596 | 647 | ||
597 | mutex_lock(&dev->object_name_lock); |
- | |
598 | idr_preload(GFP_KERNEL); |
648 | mutex_lock(&dev->object_name_lock); |
599 | /* prevent races with concurrent gem_close. */ |
649 | /* prevent races with concurrent gem_close. */ |
600 | if (obj->handle_count == 0) { |
650 | if (obj->handle_count == 0) { |
601 | ret = -ENOENT; |
651 | ret = -ENOENT; |
602 | goto err; |
652 | goto err; |
Line 603... | Line 653... | ||
603 | } |
653 | } |
604 | 654 | ||
605 | if (!obj->name) { |
655 | if (!obj->name) { |
606 | ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT); |
656 | ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_KERNEL); |
Line 607... | Line 657... | ||
607 | if (ret < 0) |
657 | if (ret < 0) |
608 | goto err; |
658 | goto err; |
Line 609... | Line 659... | ||
609 | 659 | ||
610 | obj->name = ret; |
660 | obj->name = ret; |
Line 611... | Line 661... | ||
611 | } |
661 | } |
612 | - | ||
613 | args->name = (uint64_t) obj->name; |
662 | |
614 | ret = 0; |
663 | args->name = (uint64_t) obj->name; |
- | 664 | ret = 0; |
|
- | 665 | ||
- | 666 | err: |
|
- | 667 | mutex_unlock(&dev->object_name_lock); |
|
615 | 668 | drm_gem_object_unreference_unlocked(obj); |
|
616 | err: |
669 | |
Line 617... | Line 670... | ||
617 | idr_preload_end(); |
670 | // printf("%s object %p name %d refcount %d\n", |
618 | mutex_unlock(&dev->object_name_lock); |
671 | // __FUNCTION__, obj, obj->name, obj->refcount.refcount); |
Line 659... | Line 712... | ||
659 | return ret; |
712 | return ret; |
Line 660... | Line 713... | ||
660 | 713 | ||
661 | args->handle = handle; |
714 | args->handle = handle; |
Line -... | Line 715... | ||
- | 715 | args->size = obj->size; |
|
- | 716 | ||
- | 717 | // printf("%s object %p handle %d refcount %d\n", |
|
662 | args->size = obj->size; |
718 | // __FUNCTION__, obj, handle, obj->refcount.refcount); |
663 | 719 | ||
Line 664... | Line 720... | ||
664 | return 0; |
720 | return 0; |
665 | } |
721 | } |
Line 678... | Line 734... | ||
678 | { |
734 | { |
679 | idr_init(&file_private->object_idr); |
735 | idr_init(&file_private->object_idr); |
680 | spin_lock_init(&file_private->table_lock); |
736 | spin_lock_init(&file_private->table_lock); |
681 | } |
737 | } |
Line 682... | Line -... | ||
682 | - | ||
683 | /* |
- | |
684 | * Called at device close to release the file's |
- | |
685 | * handle references on objects. |
- | |
686 | */ |
- | |
687 | static int |
- | |
688 | drm_gem_object_release_handle(int id, void *ptr, void *data) |
- | |
689 | { |
- | |
690 | struct drm_file *file_priv = data; |
- | |
691 | struct drm_gem_object *obj = ptr; |
- | |
692 | struct drm_device *dev = obj->dev; |
- | |
693 | - | ||
694 | drm_vma_node_revoke(&obj->vma_node, file_priv->filp); |
- | |
695 | - | ||
696 | if (dev->driver->gem_close_object) |
- | |
697 | dev->driver->gem_close_object(obj, file_priv); |
- | |
698 | - | ||
699 | drm_gem_object_handle_unreference_unlocked(obj); |
- | |
700 | - | ||
701 | return 0; |
- | |
702 | } |
- | |
703 | 738 | ||
704 | /** |
739 | /** |
705 | * drm_gem_release - release file-private GEM resources |
740 | * drm_gem_release - release file-private GEM resources |
706 | * @dev: drm_device which is being closed by userspace |
741 | * @dev: drm_device which is being closed by userspace |
707 | * @file_private: drm file-private structure to clean up |
742 | * @file_private: drm file-private structure to clean up |