1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 /************************************************************************** 3 * 4 * Copyright (c) 2009-2013 VMware, Inc., Palo Alto, CA., USA 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25 * USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 /* 29 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> 30 * 31 * While no substantial code is shared, the prime code is inspired by 32 * drm_prime.c, with 33 * Authors: 34 * Dave Airlie <airlied@redhat.com> 35 * Rob Clark <rob.clark@linaro.org> 36 */ 37 /** @file ttm_ref_object.c 38 * 39 * Base- and reference object implementation for the various 40 * ttm objects. Implements reference counting, minimal security checks 41 * and release on file close. 42 */ 43 44 45 #define pr_fmt(fmt) "[TTM] " fmt 46 47 #include <linux/list.h> 48 #include <linux/spinlock.h> 49 #include <linux/slab.h> 50 #include <linux/atomic.h> 51 #include "ttm_object.h" 52 53 /** 54 * struct ttm_object_file 55 * 56 * @tdev: Pointer to the ttm_object_device. 57 * 58 * @lock: Lock that protects the ref_list list and the 59 * ref_hash hash tables. 60 * 61 * @ref_list: List of ttm_ref_objects to be destroyed at 62 * file release. 63 * 64 * @ref_hash: Hash tables of ref objects, one per ttm_ref_type, 65 * for fast lookup of ref objects given a base object. 66 * 67 * @refcount: reference/usage count 68 */ 69 struct ttm_object_file { 70 struct ttm_object_device *tdev; 71 spinlock_t lock; 72 struct list_head ref_list; 73 struct drm_open_hash ref_hash[TTM_REF_NUM]; 74 struct kref refcount; 75 }; 76 77 /* 78 * struct ttm_object_device 79 * 80 * @object_lock: lock that protects the object_hash hash table. 81 * 82 * @object_hash: hash table for fast lookup of object global names. 83 * 84 * @object_count: Per device object count. 85 * 86 * This is the per-device data structure needed for ttm object management. 87 */ 88 89 struct ttm_object_device { 90 spinlock_t object_lock; 91 struct drm_open_hash object_hash; 92 atomic_t object_count; 93 struct ttm_mem_global *mem_glob; 94 struct dma_buf_ops ops; 95 void (*dmabuf_release)(struct dma_buf *dma_buf); 96 size_t dma_buf_size; 97 struct idr idr; 98 }; 99 100 /* 101 * struct ttm_ref_object 102 * 103 * @hash: Hash entry for the per-file object reference hash. 104 * 105 * @head: List entry for the per-file list of ref-objects. 106 * 107 * @kref: Ref count. 108 * 109 * @obj: Base object this ref object is referencing. 110 * 111 * @ref_type: Type of ref object. 112 * 113 * This is similar to an idr object, but it also has a hash table entry 114 * that allows lookup with a pointer to the referenced object as a key. In 115 * that way, one can easily detect whether a base object is referenced by 116 * a particular ttm_object_file. It also carries a ref count to avoid creating 117 * multiple ref objects if a ttm_object_file references the same base 118 * object more than once. 119 */ 120 121 struct ttm_ref_object { 122 struct rcu_head rcu_head; 123 struct drm_hash_item hash; 124 struct list_head head; 125 struct kref kref; 126 enum ttm_ref_type ref_type; 127 struct ttm_base_object *obj; 128 struct ttm_object_file *tfile; 129 }; 130 131 static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf); 132 133 static inline struct ttm_object_file * 134 ttm_object_file_ref(struct ttm_object_file *tfile) 135 { 136 kref_get(&tfile->refcount); 137 return tfile; 138 } 139 140 static void ttm_object_file_destroy(struct kref *kref) 141 { 142 struct ttm_object_file *tfile = 143 container_of(kref, struct ttm_object_file, refcount); 144 145 kfree(tfile); 146 } 147 148 149 static inline void ttm_object_file_unref(struct ttm_object_file **p_tfile) 150 { 151 struct ttm_object_file *tfile = *p_tfile; 152 153 *p_tfile = NULL; 154 kref_put(&tfile->refcount, ttm_object_file_destroy); 155 } 156 157 158 int ttm_base_object_init(struct ttm_object_file *tfile, 159 struct ttm_base_object *base, 160 bool shareable, 161 enum ttm_object_type object_type, 162 void (*refcount_release) (struct ttm_base_object **), 163 void (*ref_obj_release) (struct ttm_base_object *, 164 enum ttm_ref_type ref_type)) 165 { 166 struct ttm_object_device *tdev = tfile->tdev; 167 int ret; 168 169 base->shareable = shareable; 170 base->tfile = ttm_object_file_ref(tfile); 171 base->refcount_release = refcount_release; 172 base->ref_obj_release = ref_obj_release; 173 base->object_type = object_type; 174 kref_init(&base->refcount); 175 idr_preload(GFP_KERNEL); 176 spin_lock(&tdev->object_lock); 177 ret = idr_alloc(&tdev->idr, base, 1, 0, GFP_NOWAIT); 178 spin_unlock(&tdev->object_lock); 179 idr_preload_end(); 180 if (ret < 0) 181 return ret; 182 183 base->handle = ret; 184 ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); 185 if (unlikely(ret != 0)) 186 goto out_err1; 187 188 ttm_base_object_unref(&base); 189 190 return 0; 191 out_err1: 192 spin_lock(&tdev->object_lock); 193 idr_remove(&tdev->idr, base->handle); 194 spin_unlock(&tdev->object_lock); 195 return ret; 196 } 197 198 static void ttm_release_base(struct kref *kref) 199 { 200 struct ttm_base_object *base = 201 container_of(kref, struct ttm_base_object, refcount); 202 struct ttm_object_device *tdev = base->tfile->tdev; 203 204 spin_lock(&tdev->object_lock); 205 idr_remove(&tdev->idr, base->handle); 206 spin_unlock(&tdev->object_lock); 207 208 /* 209 * Note: We don't use synchronize_rcu() here because it's far 210 * too slow. It's up to the user to free the object using 211 * call_rcu() or ttm_base_object_kfree(). 212 */ 213 214 ttm_object_file_unref(&base->tfile); 215 if (base->refcount_release) 216 base->refcount_release(&base); 217 } 218 219 void ttm_base_object_unref(struct ttm_base_object **p_base) 220 { 221 struct ttm_base_object *base = *p_base; 222 223 *p_base = NULL; 224 225 kref_put(&base->refcount, ttm_release_base); 226 } 227 228 /** 229 * ttm_base_object_noref_lookup - look up a base object without reference 230 * @tfile: The struct ttm_object_file the object is registered with. 231 * @key: The object handle. 232 * 233 * This function looks up a ttm base object and returns a pointer to it 234 * without refcounting the pointer. The returned pointer is only valid 235 * until ttm_base_object_noref_release() is called, and the object 236 * pointed to by the returned pointer may be doomed. Any persistent usage 237 * of the object requires a refcount to be taken using kref_get_unless_zero(). 238 * Iff this function returns successfully it needs to be paired with 239 * ttm_base_object_noref_release() and no sleeping- or scheduling functions 240 * may be called inbetween these function callse. 241 * 242 * Return: A pointer to the object if successful or NULL otherwise. 243 */ 244 struct ttm_base_object * 245 ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint32_t key) 246 { 247 struct drm_hash_item *hash; 248 struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE]; 249 int ret; 250 251 rcu_read_lock(); 252 ret = drm_ht_find_item_rcu(ht, key, &hash); 253 if (ret) { 254 rcu_read_unlock(); 255 return NULL; 256 } 257 258 __release(RCU); 259 return drm_hash_entry(hash, struct ttm_ref_object, hash)->obj; 260 } 261 EXPORT_SYMBOL(ttm_base_object_noref_lookup); 262 263 struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, 264 uint32_t key) 265 { 266 struct ttm_base_object *base = NULL; 267 struct drm_hash_item *hash; 268 struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE]; 269 int ret; 270 271 rcu_read_lock(); 272 ret = drm_ht_find_item_rcu(ht, key, &hash); 273 274 if (likely(ret == 0)) { 275 base = drm_hash_entry(hash, struct ttm_ref_object, hash)->obj; 276 if (!kref_get_unless_zero(&base->refcount)) 277 base = NULL; 278 } 279 rcu_read_unlock(); 280 281 return base; 282 } 283 284 struct ttm_base_object * 285 ttm_base_object_lookup_for_ref(struct ttm_object_device *tdev, uint32_t key) 286 { 287 struct ttm_base_object *base; 288 289 rcu_read_lock(); 290 base = idr_find(&tdev->idr, key); 291 292 if (base && !kref_get_unless_zero(&base->refcount)) 293 base = NULL; 294 rcu_read_unlock(); 295 296 return base; 297 } 298 299 /** 300 * ttm_ref_object_exists - Check whether a caller has a valid ref object 301 * (has opened) a base object. 302 * 303 * @tfile: Pointer to a struct ttm_object_file identifying the caller. 304 * @base: Pointer to a struct base object. 305 * 306 * Checks wether the caller identified by @tfile has put a valid USAGE 307 * reference object on the base object identified by @base. 308 */ 309 bool ttm_ref_object_exists(struct ttm_object_file *tfile, 310 struct ttm_base_object *base) 311 { 312 struct drm_open_hash *ht = &tfile->ref_hash[TTM_REF_USAGE]; 313 struct drm_hash_item *hash; 314 struct ttm_ref_object *ref; 315 316 rcu_read_lock(); 317 if (unlikely(drm_ht_find_item_rcu(ht, base->handle, &hash) != 0)) 318 goto out_false; 319 320 /* 321 * Verify that the ref object is really pointing to our base object. 322 * Our base object could actually be dead, and the ref object pointing 323 * to another base object with the same handle. 324 */ 325 ref = drm_hash_entry(hash, struct ttm_ref_object, hash); 326 if (unlikely(base != ref->obj)) 327 goto out_false; 328 329 /* 330 * Verify that the ref->obj pointer was actually valid! 331 */ 332 rmb(); 333 if (unlikely(kref_read(&ref->kref) == 0)) 334 goto out_false; 335 336 rcu_read_unlock(); 337 return true; 338 339 out_false: 340 rcu_read_unlock(); 341 return false; 342 } 343 344 int ttm_ref_object_add(struct ttm_object_file *tfile, 345 struct ttm_base_object *base, 346 enum ttm_ref_type ref_type, bool *existed, 347 bool require_existed) 348 { 349 struct drm_open_hash *ht = &tfile->ref_hash[ref_type]; 350 struct ttm_ref_object *ref; 351 struct drm_hash_item *hash; 352 struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob; 353 struct ttm_operation_ctx ctx = { 354 .interruptible = false, 355 .no_wait_gpu = false 356 }; 357 int ret = -EINVAL; 358 359 if (base->tfile != tfile && !base->shareable) 360 return -EPERM; 361 362 if (existed != NULL) 363 *existed = true; 364 365 while (ret == -EINVAL) { 366 rcu_read_lock(); 367 ret = drm_ht_find_item_rcu(ht, base->handle, &hash); 368 369 if (ret == 0) { 370 ref = drm_hash_entry(hash, struct ttm_ref_object, hash); 371 if (kref_get_unless_zero(&ref->kref)) { 372 rcu_read_unlock(); 373 break; 374 } 375 } 376 377 rcu_read_unlock(); 378 if (require_existed) 379 return -EPERM; 380 381 ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref), 382 &ctx); 383 if (unlikely(ret != 0)) 384 return ret; 385 ref = kmalloc(sizeof(*ref), GFP_KERNEL); 386 if (unlikely(ref == NULL)) { 387 ttm_mem_global_free(mem_glob, sizeof(*ref)); 388 return -ENOMEM; 389 } 390 391 ref->hash.key = base->handle; 392 ref->obj = base; 393 ref->tfile = tfile; 394 ref->ref_type = ref_type; 395 kref_init(&ref->kref); 396 397 spin_lock(&tfile->lock); 398 ret = drm_ht_insert_item_rcu(ht, &ref->hash); 399 400 if (likely(ret == 0)) { 401 list_add_tail(&ref->head, &tfile->ref_list); 402 kref_get(&base->refcount); 403 spin_unlock(&tfile->lock); 404 if (existed != NULL) 405 *existed = false; 406 break; 407 } 408 409 spin_unlock(&tfile->lock); 410 BUG_ON(ret != -EINVAL); 411 412 ttm_mem_global_free(mem_glob, sizeof(*ref)); 413 kfree(ref); 414 } 415 416 return ret; 417 } 418 419 static void __releases(tfile->lock) __acquires(tfile->lock) 420 ttm_ref_object_release(struct kref *kref) 421 { 422 struct ttm_ref_object *ref = 423 container_of(kref, struct ttm_ref_object, kref); 424 struct ttm_base_object *base = ref->obj; 425 struct ttm_object_file *tfile = ref->tfile; 426 struct drm_open_hash *ht; 427 struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob; 428 429 ht = &tfile->ref_hash[ref->ref_type]; 430 (void)drm_ht_remove_item_rcu(ht, &ref->hash); 431 list_del(&ref->head); 432 spin_unlock(&tfile->lock); 433 434 if (ref->ref_type != TTM_REF_USAGE && base->ref_obj_release) 435 base->ref_obj_release(base, ref->ref_type); 436 437 ttm_base_object_unref(&ref->obj); 438 ttm_mem_global_free(mem_glob, sizeof(*ref)); 439 kfree_rcu(ref, rcu_head); 440 spin_lock(&tfile->lock); 441 } 442 443 int ttm_ref_object_base_unref(struct ttm_object_file *tfile, 444 unsigned long key, enum ttm_ref_type ref_type) 445 { 446 struct drm_open_hash *ht = &tfile->ref_hash[ref_type]; 447 struct ttm_ref_object *ref; 448 struct drm_hash_item *hash; 449 int ret; 450 451 spin_lock(&tfile->lock); 452 ret = drm_ht_find_item(ht, key, &hash); 453 if (unlikely(ret != 0)) { 454 spin_unlock(&tfile->lock); 455 return -EINVAL; 456 } 457 ref = drm_hash_entry(hash, struct ttm_ref_object, hash); 458 kref_put(&ref->kref, ttm_ref_object_release); 459 spin_unlock(&tfile->lock); 460 return 0; 461 } 462 463 void ttm_object_file_release(struct ttm_object_file **p_tfile) 464 { 465 struct ttm_ref_object *ref; 466 struct list_head *list; 467 unsigned int i; 468 struct ttm_object_file *tfile = *p_tfile; 469 470 *p_tfile = NULL; 471 spin_lock(&tfile->lock); 472 473 /* 474 * Since we release the lock within the loop, we have to 475 * restart it from the beginning each time. 476 */ 477 478 while (!list_empty(&tfile->ref_list)) { 479 list = tfile->ref_list.next; 480 ref = list_entry(list, struct ttm_ref_object, head); 481 ttm_ref_object_release(&ref->kref); 482 } 483 484 spin_unlock(&tfile->lock); 485 for (i = 0; i < TTM_REF_NUM; ++i) 486 drm_ht_remove(&tfile->ref_hash[i]); 487 488 ttm_object_file_unref(&tfile); 489 } 490 491 struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev, 492 unsigned int hash_order) 493 { 494 struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL); 495 unsigned int i; 496 unsigned int j = 0; 497 int ret; 498 499 if (unlikely(tfile == NULL)) 500 return NULL; 501 502 spin_lock_init(&tfile->lock); 503 tfile->tdev = tdev; 504 kref_init(&tfile->refcount); 505 INIT_LIST_HEAD(&tfile->ref_list); 506 507 for (i = 0; i < TTM_REF_NUM; ++i) { 508 ret = drm_ht_create(&tfile->ref_hash[i], hash_order); 509 if (ret) { 510 j = i; 511 goto out_err; 512 } 513 } 514 515 return tfile; 516 out_err: 517 for (i = 0; i < j; ++i) 518 drm_ht_remove(&tfile->ref_hash[i]); 519 520 kfree(tfile); 521 522 return NULL; 523 } 524 525 struct ttm_object_device * 526 ttm_object_device_init(struct ttm_mem_global *mem_glob, 527 unsigned int hash_order, 528 const struct dma_buf_ops *ops) 529 { 530 struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL); 531 int ret; 532 533 if (unlikely(tdev == NULL)) 534 return NULL; 535 536 tdev->mem_glob = mem_glob; 537 spin_lock_init(&tdev->object_lock); 538 atomic_set(&tdev->object_count, 0); 539 ret = drm_ht_create(&tdev->object_hash, hash_order); 540 if (ret != 0) 541 goto out_no_object_hash; 542 543 idr_init_base(&tdev->idr, 1); 544 tdev->ops = *ops; 545 tdev->dmabuf_release = tdev->ops.release; 546 tdev->ops.release = ttm_prime_dmabuf_release; 547 tdev->dma_buf_size = ttm_round_pot(sizeof(struct dma_buf)) + 548 ttm_round_pot(sizeof(struct file)); 549 return tdev; 550 551 out_no_object_hash: 552 kfree(tdev); 553 return NULL; 554 } 555 556 void ttm_object_device_release(struct ttm_object_device **p_tdev) 557 { 558 struct ttm_object_device *tdev = *p_tdev; 559 560 *p_tdev = NULL; 561 562 WARN_ON_ONCE(!idr_is_empty(&tdev->idr)); 563 idr_destroy(&tdev->idr); 564 drm_ht_remove(&tdev->object_hash); 565 566 kfree(tdev); 567 } 568 569 /** 570 * get_dma_buf_unless_doomed - get a dma_buf reference if possible. 571 * 572 * @dmabuf: Non-refcounted pointer to a struct dma-buf. 573 * 574 * Obtain a file reference from a lookup structure that doesn't refcount 575 * the file, but synchronizes with its release method to make sure it has 576 * not been freed yet. See for example kref_get_unless_zero documentation. 577 * Returns true if refcounting succeeds, false otherwise. 578 * 579 * Nobody really wants this as a public API yet, so let it mature here 580 * for some time... 581 */ 582 static bool __must_check get_dma_buf_unless_doomed(struct dma_buf *dmabuf) 583 { 584 return atomic_long_inc_not_zero(&dmabuf->file->f_count) != 0L; 585 } 586 587 /** 588 * ttm_prime_refcount_release - refcount release method for a prime object. 589 * 590 * @p_base: Pointer to ttm_base_object pointer. 591 * 592 * This is a wrapper that calls the refcount_release founction of the 593 * underlying object. At the same time it cleans up the prime object. 594 * This function is called when all references to the base object we 595 * derive from are gone. 596 */ 597 static void ttm_prime_refcount_release(struct ttm_base_object **p_base) 598 { 599 struct ttm_base_object *base = *p_base; 600 struct ttm_prime_object *prime; 601 602 *p_base = NULL; 603 prime = container_of(base, struct ttm_prime_object, base); 604 BUG_ON(prime->dma_buf != NULL); 605 mutex_destroy(&prime->mutex); 606 if (prime->refcount_release) 607 prime->refcount_release(&base); 608 } 609 610 /** 611 * ttm_prime_dmabuf_release - Release method for the dma-bufs we export 612 * 613 * @dma_buf: 614 * 615 * This function first calls the dma_buf release method the driver 616 * provides. Then it cleans up our dma_buf pointer used for lookup, 617 * and finally releases the reference the dma_buf has on our base 618 * object. 619 */ 620 static void ttm_prime_dmabuf_release(struct dma_buf *dma_buf) 621 { 622 struct ttm_prime_object *prime = 623 (struct ttm_prime_object *) dma_buf->priv; 624 struct ttm_base_object *base = &prime->base; 625 struct ttm_object_device *tdev = base->tfile->tdev; 626 627 if (tdev->dmabuf_release) 628 tdev->dmabuf_release(dma_buf); 629 mutex_lock(&prime->mutex); 630 if (prime->dma_buf == dma_buf) 631 prime->dma_buf = NULL; 632 mutex_unlock(&prime->mutex); 633 ttm_mem_global_free(tdev->mem_glob, tdev->dma_buf_size); 634 ttm_base_object_unref(&base); 635 } 636 637 /** 638 * ttm_prime_fd_to_handle - Get a base object handle from a prime fd 639 * 640 * @tfile: A struct ttm_object_file identifying the caller. 641 * @fd: The prime / dmabuf fd. 642 * @handle: The returned handle. 643 * 644 * This function returns a handle to an object that previously exported 645 * a dma-buf. Note that we don't handle imports yet, because we simply 646 * have no consumers of that implementation. 647 */ 648 int ttm_prime_fd_to_handle(struct ttm_object_file *tfile, 649 int fd, u32 *handle) 650 { 651 struct ttm_object_device *tdev = tfile->tdev; 652 struct dma_buf *dma_buf; 653 struct ttm_prime_object *prime; 654 struct ttm_base_object *base; 655 int ret; 656 657 dma_buf = dma_buf_get(fd); 658 if (IS_ERR(dma_buf)) 659 return PTR_ERR(dma_buf); 660 661 if (dma_buf->ops != &tdev->ops) 662 return -ENOSYS; 663 664 prime = (struct ttm_prime_object *) dma_buf->priv; 665 base = &prime->base; 666 *handle = base->handle; 667 ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL, false); 668 669 dma_buf_put(dma_buf); 670 671 return ret; 672 } 673 674 /** 675 * ttm_prime_handle_to_fd - Return a dma_buf fd from a ttm prime object 676 * 677 * @tfile: Struct ttm_object_file identifying the caller. 678 * @handle: Handle to the object we're exporting from. 679 * @flags: flags for dma-buf creation. We just pass them on. 680 * @prime_fd: The returned file descriptor. 681 * 682 */ 683 int ttm_prime_handle_to_fd(struct ttm_object_file *tfile, 684 uint32_t handle, uint32_t flags, 685 int *prime_fd) 686 { 687 struct ttm_object_device *tdev = tfile->tdev; 688 struct ttm_base_object *base; 689 struct dma_buf *dma_buf; 690 struct ttm_prime_object *prime; 691 int ret; 692 693 base = ttm_base_object_lookup(tfile, handle); 694 if (unlikely(base == NULL || 695 base->object_type != ttm_prime_type)) { 696 ret = -ENOENT; 697 goto out_unref; 698 } 699 700 prime = container_of(base, struct ttm_prime_object, base); 701 if (unlikely(!base->shareable)) { 702 ret = -EPERM; 703 goto out_unref; 704 } 705 706 ret = mutex_lock_interruptible(&prime->mutex); 707 if (unlikely(ret != 0)) { 708 ret = -ERESTARTSYS; 709 goto out_unref; 710 } 711 712 dma_buf = prime->dma_buf; 713 if (!dma_buf || !get_dma_buf_unless_doomed(dma_buf)) { 714 DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 715 struct ttm_operation_ctx ctx = { 716 .interruptible = true, 717 .no_wait_gpu = false 718 }; 719 exp_info.ops = &tdev->ops; 720 exp_info.size = prime->size; 721 exp_info.flags = flags; 722 exp_info.priv = prime; 723 724 /* 725 * Need to create a new dma_buf, with memory accounting. 726 */ 727 ret = ttm_mem_global_alloc(tdev->mem_glob, tdev->dma_buf_size, 728 &ctx); 729 if (unlikely(ret != 0)) { 730 mutex_unlock(&prime->mutex); 731 goto out_unref; 732 } 733 734 dma_buf = dma_buf_export(&exp_info); 735 if (IS_ERR(dma_buf)) { 736 ret = PTR_ERR(dma_buf); 737 ttm_mem_global_free(tdev->mem_glob, 738 tdev->dma_buf_size); 739 mutex_unlock(&prime->mutex); 740 goto out_unref; 741 } 742 743 /* 744 * dma_buf has taken the base object reference 745 */ 746 base = NULL; 747 prime->dma_buf = dma_buf; 748 } 749 mutex_unlock(&prime->mutex); 750 751 ret = dma_buf_fd(dma_buf, flags); 752 if (ret >= 0) { 753 *prime_fd = ret; 754 ret = 0; 755 } else 756 dma_buf_put(dma_buf); 757 758 out_unref: 759 if (base) 760 ttm_base_object_unref(&base); 761 return ret; 762 } 763 764 /** 765 * ttm_prime_object_init - Initialize a ttm_prime_object 766 * 767 * @tfile: struct ttm_object_file identifying the caller 768 * @size: The size of the dma_bufs we export. 769 * @prime: The object to be initialized. 770 * @shareable: See ttm_base_object_init 771 * @type: See ttm_base_object_init 772 * @refcount_release: See ttm_base_object_init 773 * @ref_obj_release: See ttm_base_object_init 774 * 775 * Initializes an object which is compatible with the drm_prime model 776 * for data sharing between processes and devices. 777 */ 778 int ttm_prime_object_init(struct ttm_object_file *tfile, size_t size, 779 struct ttm_prime_object *prime, bool shareable, 780 enum ttm_object_type type, 781 void (*refcount_release) (struct ttm_base_object **), 782 void (*ref_obj_release) (struct ttm_base_object *, 783 enum ttm_ref_type ref_type)) 784 { 785 mutex_init(&prime->mutex); 786 prime->size = PAGE_ALIGN(size); 787 prime->real_type = type; 788 prime->dma_buf = NULL; 789 prime->refcount_release = refcount_release; 790 return ttm_base_object_init(tfile, &prime->base, shareable, 791 ttm_prime_type, 792 ttm_prime_refcount_release, 793 ref_obj_release); 794 } 795