1 /* 2 * Copyright (C) 2012-2014 Canonical Ltd (Maarten Lankhorst) 3 * 4 * Based on bo.c which bears the following copyright notice, 5 * but is dual licensed: 6 * 7 * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA 8 * All Rights Reserved. 9 * 10 * Permission is hereby granted, free of charge, to any person obtaining a 11 * copy of this software and associated documentation files (the 12 * "Software"), to deal in the Software without restriction, including 13 * without limitation the rights to use, copy, modify, merge, publish, 14 * distribute, sub license, and/or sell copies of the Software, and to 15 * permit persons to whom the Software is furnished to do so, subject to 16 * the following conditions: 17 * 18 * The above copyright notice and this permission notice (including the 19 * next paragraph) shall be included in all copies or substantial portions 20 * of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 25 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 26 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 27 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 28 * USE OR OTHER DEALINGS IN THE SOFTWARE. 29 * 30 **************************************************************************/ 31 /* 32 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> 33 */ 34 35 #include <linux/dma-resv.h> 36 #include <linux/export.h> 37 #include <linux/mm.h> 38 #include <linux/sched/mm.h> 39 #include <linux/mmu_notifier.h> 40 41 /** 42 * DOC: Reservation Object Overview 43 * 44 * The reservation object provides a mechanism to manage shared and 45 * exclusive fences associated with a buffer. A reservation object 46 * can have attached one exclusive fence (normally associated with 47 * write operations) or N shared fences (read operations). The RCU 48 * mechanism is used to protect read access to fences from locked 49 * write-side updates. 50 */ 51 52 DEFINE_WD_CLASS(reservation_ww_class); 53 EXPORT_SYMBOL(reservation_ww_class); 54 55 /** 56 * dma_resv_list_alloc - allocate fence list 57 * @shared_max: number of fences we need space for 58 * 59 * Allocate a new dma_resv_list and make sure to correctly initialize 60 * shared_max. 61 */ 62 static struct dma_resv_list *dma_resv_list_alloc(unsigned int shared_max) 63 { 64 struct dma_resv_list *list; 65 66 list = kmalloc(offsetof(typeof(*list), shared[shared_max]), GFP_KERNEL); 67 if (!list) 68 return NULL; 69 70 list->shared_max = (ksize(list) - offsetof(typeof(*list), shared)) / 71 sizeof(*list->shared); 72 73 return list; 74 } 75 76 /** 77 * dma_resv_list_free - free fence list 78 * @list: list to free 79 * 80 * Free a dma_resv_list and make sure to drop all references. 81 */ 82 static void dma_resv_list_free(struct dma_resv_list *list) 83 { 84 unsigned int i; 85 86 if (!list) 87 return; 88 89 for (i = 0; i < list->shared_count; ++i) 90 dma_fence_put(rcu_dereference_protected(list->shared[i], true)); 91 92 kfree_rcu(list, rcu); 93 } 94 95 #if IS_ENABLED(CONFIG_LOCKDEP) 96 static int __init dma_resv_lockdep(void) 97 { 98 struct mm_struct *mm = mm_alloc(); 99 struct ww_acquire_ctx ctx; 100 struct dma_resv obj; 101 int ret; 102 103 if (!mm) 104 return -ENOMEM; 105 106 dma_resv_init(&obj); 107 108 mmap_read_lock(mm); 109 ww_acquire_init(&ctx, &reservation_ww_class); 110 ret = dma_resv_lock(&obj, &ctx); 111 if (ret == -EDEADLK) 112 dma_resv_lock_slow(&obj, &ctx); 113 fs_reclaim_acquire(GFP_KERNEL); 114 #ifdef CONFIG_MMU_NOTIFIER 115 lock_map_acquire(&__mmu_notifier_invalidate_range_start_map); 116 __dma_fence_might_wait(); 117 lock_map_release(&__mmu_notifier_invalidate_range_start_map); 118 #else 119 __dma_fence_might_wait(); 120 #endif 121 fs_reclaim_release(GFP_KERNEL); 122 ww_mutex_unlock(&obj.lock); 123 ww_acquire_fini(&ctx); 124 mmap_read_unlock(mm); 125 126 mmput(mm); 127 128 return 0; 129 } 130 subsys_initcall(dma_resv_lockdep); 131 #endif 132 133 /** 134 * dma_resv_init - initialize a reservation object 135 * @obj: the reservation object 136 */ 137 void dma_resv_init(struct dma_resv *obj) 138 { 139 ww_mutex_init(&obj->lock, &reservation_ww_class); 140 seqcount_ww_mutex_init(&obj->seq, &obj->lock); 141 142 RCU_INIT_POINTER(obj->fence, NULL); 143 RCU_INIT_POINTER(obj->fence_excl, NULL); 144 } 145 EXPORT_SYMBOL(dma_resv_init); 146 147 /** 148 * dma_resv_fini - destroys a reservation object 149 * @obj: the reservation object 150 */ 151 void dma_resv_fini(struct dma_resv *obj) 152 { 153 struct dma_resv_list *fobj; 154 struct dma_fence *excl; 155 156 /* 157 * This object should be dead and all references must have 158 * been released to it, so no need to be protected with rcu. 159 */ 160 excl = rcu_dereference_protected(obj->fence_excl, 1); 161 if (excl) 162 dma_fence_put(excl); 163 164 fobj = rcu_dereference_protected(obj->fence, 1); 165 dma_resv_list_free(fobj); 166 ww_mutex_destroy(&obj->lock); 167 } 168 EXPORT_SYMBOL(dma_resv_fini); 169 170 /** 171 * dma_resv_reserve_shared - Reserve space to add shared fences to 172 * a dma_resv. 173 * @obj: reservation object 174 * @num_fences: number of fences we want to add 175 * 176 * Should be called before dma_resv_add_shared_fence(). Must 177 * be called with obj->lock held. 178 * 179 * RETURNS 180 * Zero for success, or -errno 181 */ 182 int dma_resv_reserve_shared(struct dma_resv *obj, unsigned int num_fences) 183 { 184 struct dma_resv_list *old, *new; 185 unsigned int i, j, k, max; 186 187 dma_resv_assert_held(obj); 188 189 old = dma_resv_get_list(obj); 190 191 if (old && old->shared_max) { 192 if ((old->shared_count + num_fences) <= old->shared_max) 193 return 0; 194 else 195 max = max(old->shared_count + num_fences, 196 old->shared_max * 2); 197 } else { 198 max = 4; 199 } 200 201 new = dma_resv_list_alloc(max); 202 if (!new) 203 return -ENOMEM; 204 205 /* 206 * no need to bump fence refcounts, rcu_read access 207 * requires the use of kref_get_unless_zero, and the 208 * references from the old struct are carried over to 209 * the new. 210 */ 211 for (i = 0, j = 0, k = max; i < (old ? old->shared_count : 0); ++i) { 212 struct dma_fence *fence; 213 214 fence = rcu_dereference_protected(old->shared[i], 215 dma_resv_held(obj)); 216 if (dma_fence_is_signaled(fence)) 217 RCU_INIT_POINTER(new->shared[--k], fence); 218 else 219 RCU_INIT_POINTER(new->shared[j++], fence); 220 } 221 new->shared_count = j; 222 223 /* 224 * We are not changing the effective set of fences here so can 225 * merely update the pointer to the new array; both existing 226 * readers and new readers will see exactly the same set of 227 * active (unsignaled) shared fences. Individual fences and the 228 * old array are protected by RCU and so will not vanish under 229 * the gaze of the rcu_read_lock() readers. 230 */ 231 rcu_assign_pointer(obj->fence, new); 232 233 if (!old) 234 return 0; 235 236 /* Drop the references to the signaled fences */ 237 for (i = k; i < max; ++i) { 238 struct dma_fence *fence; 239 240 fence = rcu_dereference_protected(new->shared[i], 241 dma_resv_held(obj)); 242 dma_fence_put(fence); 243 } 244 kfree_rcu(old, rcu); 245 246 return 0; 247 } 248 EXPORT_SYMBOL(dma_resv_reserve_shared); 249 250 /** 251 * dma_resv_add_shared_fence - Add a fence to a shared slot 252 * @obj: the reservation object 253 * @fence: the shared fence to add 254 * 255 * Add a fence to a shared slot, obj->lock must be held, and 256 * dma_resv_reserve_shared() has been called. 257 */ 258 void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence) 259 { 260 struct dma_resv_list *fobj; 261 struct dma_fence *old; 262 unsigned int i, count; 263 264 dma_fence_get(fence); 265 266 dma_resv_assert_held(obj); 267 268 fobj = dma_resv_get_list(obj); 269 count = fobj->shared_count; 270 271 write_seqcount_begin(&obj->seq); 272 273 for (i = 0; i < count; ++i) { 274 275 old = rcu_dereference_protected(fobj->shared[i], 276 dma_resv_held(obj)); 277 if (old->context == fence->context || 278 dma_fence_is_signaled(old)) 279 goto replace; 280 } 281 282 BUG_ON(fobj->shared_count >= fobj->shared_max); 283 old = NULL; 284 count++; 285 286 replace: 287 RCU_INIT_POINTER(fobj->shared[i], fence); 288 /* pointer update must be visible before we extend the shared_count */ 289 smp_store_mb(fobj->shared_count, count); 290 291 write_seqcount_end(&obj->seq); 292 dma_fence_put(old); 293 } 294 EXPORT_SYMBOL(dma_resv_add_shared_fence); 295 296 /** 297 * dma_resv_add_excl_fence - Add an exclusive fence. 298 * @obj: the reservation object 299 * @fence: the shared fence to add 300 * 301 * Add a fence to the exclusive slot. The obj->lock must be held. 302 */ 303 void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) 304 { 305 struct dma_fence *old_fence = dma_resv_get_excl(obj); 306 struct dma_resv_list *old; 307 u32 i = 0; 308 309 dma_resv_assert_held(obj); 310 311 old = dma_resv_get_list(obj); 312 if (old) 313 i = old->shared_count; 314 315 if (fence) 316 dma_fence_get(fence); 317 318 write_seqcount_begin(&obj->seq); 319 /* write_seqcount_begin provides the necessary memory barrier */ 320 RCU_INIT_POINTER(obj->fence_excl, fence); 321 if (old) 322 old->shared_count = 0; 323 write_seqcount_end(&obj->seq); 324 325 /* inplace update, no shared fences */ 326 while (i--) 327 dma_fence_put(rcu_dereference_protected(old->shared[i], 328 dma_resv_held(obj))); 329 330 dma_fence_put(old_fence); 331 } 332 EXPORT_SYMBOL(dma_resv_add_excl_fence); 333 334 /** 335 * dma_resv_copy_fences - Copy all fences from src to dst. 336 * @dst: the destination reservation object 337 * @src: the source reservation object 338 * 339 * Copy all fences from src to dst. dst-lock must be held. 340 */ 341 int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src) 342 { 343 struct dma_resv_list *src_list, *dst_list; 344 struct dma_fence *old, *new; 345 unsigned i; 346 347 dma_resv_assert_held(dst); 348 349 rcu_read_lock(); 350 src_list = rcu_dereference(src->fence); 351 352 retry: 353 if (src_list) { 354 unsigned shared_count = src_list->shared_count; 355 356 rcu_read_unlock(); 357 358 dst_list = dma_resv_list_alloc(shared_count); 359 if (!dst_list) 360 return -ENOMEM; 361 362 rcu_read_lock(); 363 src_list = rcu_dereference(src->fence); 364 if (!src_list || src_list->shared_count > shared_count) { 365 kfree(dst_list); 366 goto retry; 367 } 368 369 dst_list->shared_count = 0; 370 for (i = 0; i < src_list->shared_count; ++i) { 371 struct dma_fence *fence; 372 373 fence = rcu_dereference(src_list->shared[i]); 374 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, 375 &fence->flags)) 376 continue; 377 378 if (!dma_fence_get_rcu(fence)) { 379 dma_resv_list_free(dst_list); 380 src_list = rcu_dereference(src->fence); 381 goto retry; 382 } 383 384 if (dma_fence_is_signaled(fence)) { 385 dma_fence_put(fence); 386 continue; 387 } 388 389 rcu_assign_pointer(dst_list->shared[dst_list->shared_count++], fence); 390 } 391 } else { 392 dst_list = NULL; 393 } 394 395 new = dma_fence_get_rcu_safe(&src->fence_excl); 396 rcu_read_unlock(); 397 398 src_list = dma_resv_get_list(dst); 399 old = dma_resv_get_excl(dst); 400 401 write_seqcount_begin(&dst->seq); 402 /* write_seqcount_begin provides the necessary memory barrier */ 403 RCU_INIT_POINTER(dst->fence_excl, new); 404 RCU_INIT_POINTER(dst->fence, dst_list); 405 write_seqcount_end(&dst->seq); 406 407 dma_resv_list_free(src_list); 408 dma_fence_put(old); 409 410 return 0; 411 } 412 EXPORT_SYMBOL(dma_resv_copy_fences); 413 414 /** 415 * dma_resv_get_fences_rcu - Get an object's shared and exclusive 416 * fences without update side lock held 417 * @obj: the reservation object 418 * @pfence_excl: the returned exclusive fence (or NULL) 419 * @pshared_count: the number of shared fences returned 420 * @pshared: the array of shared fence ptrs returned (array is krealloc'd to 421 * the required size, and must be freed by caller) 422 * 423 * Retrieve all fences from the reservation object. If the pointer for the 424 * exclusive fence is not specified the fence is put into the array of the 425 * shared fences as well. Returns either zero or -ENOMEM. 426 */ 427 int dma_resv_get_fences_rcu(struct dma_resv *obj, 428 struct dma_fence **pfence_excl, 429 unsigned *pshared_count, 430 struct dma_fence ***pshared) 431 { 432 struct dma_fence **shared = NULL; 433 struct dma_fence *fence_excl; 434 unsigned int shared_count; 435 int ret = 1; 436 437 do { 438 struct dma_resv_list *fobj; 439 unsigned int i, seq; 440 size_t sz = 0; 441 442 shared_count = i = 0; 443 444 rcu_read_lock(); 445 seq = read_seqcount_begin(&obj->seq); 446 447 fence_excl = rcu_dereference(obj->fence_excl); 448 if (fence_excl && !dma_fence_get_rcu(fence_excl)) 449 goto unlock; 450 451 fobj = rcu_dereference(obj->fence); 452 if (fobj) 453 sz += sizeof(*shared) * fobj->shared_max; 454 455 if (!pfence_excl && fence_excl) 456 sz += sizeof(*shared); 457 458 if (sz) { 459 struct dma_fence **nshared; 460 461 nshared = krealloc(shared, sz, 462 GFP_NOWAIT | __GFP_NOWARN); 463 if (!nshared) { 464 rcu_read_unlock(); 465 466 dma_fence_put(fence_excl); 467 fence_excl = NULL; 468 469 nshared = krealloc(shared, sz, GFP_KERNEL); 470 if (nshared) { 471 shared = nshared; 472 continue; 473 } 474 475 ret = -ENOMEM; 476 break; 477 } 478 shared = nshared; 479 shared_count = fobj ? fobj->shared_count : 0; 480 for (i = 0; i < shared_count; ++i) { 481 shared[i] = rcu_dereference(fobj->shared[i]); 482 if (!dma_fence_get_rcu(shared[i])) 483 break; 484 } 485 } 486 487 if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) { 488 while (i--) 489 dma_fence_put(shared[i]); 490 dma_fence_put(fence_excl); 491 goto unlock; 492 } 493 494 ret = 0; 495 unlock: 496 rcu_read_unlock(); 497 } while (ret); 498 499 if (pfence_excl) 500 *pfence_excl = fence_excl; 501 else if (fence_excl) 502 shared[shared_count++] = fence_excl; 503 504 if (!shared_count) { 505 kfree(shared); 506 shared = NULL; 507 } 508 509 *pshared_count = shared_count; 510 *pshared = shared; 511 return ret; 512 } 513 EXPORT_SYMBOL_GPL(dma_resv_get_fences_rcu); 514 515 /** 516 * dma_resv_wait_timeout_rcu - Wait on reservation's objects 517 * shared and/or exclusive fences. 518 * @obj: the reservation object 519 * @wait_all: if true, wait on all fences, else wait on just exclusive fence 520 * @intr: if true, do interruptible wait 521 * @timeout: timeout value in jiffies or zero to return immediately 522 * 523 * RETURNS 524 * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or 525 * greater than zer on success. 526 */ 527 long dma_resv_wait_timeout_rcu(struct dma_resv *obj, 528 bool wait_all, bool intr, 529 unsigned long timeout) 530 { 531 struct dma_fence *fence; 532 unsigned seq, shared_count; 533 long ret = timeout ? timeout : 1; 534 int i; 535 536 retry: 537 shared_count = 0; 538 seq = read_seqcount_begin(&obj->seq); 539 rcu_read_lock(); 540 i = -1; 541 542 fence = rcu_dereference(obj->fence_excl); 543 if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { 544 if (!dma_fence_get_rcu(fence)) 545 goto unlock_retry; 546 547 if (dma_fence_is_signaled(fence)) { 548 dma_fence_put(fence); 549 fence = NULL; 550 } 551 552 } else { 553 fence = NULL; 554 } 555 556 if (wait_all) { 557 struct dma_resv_list *fobj = rcu_dereference(obj->fence); 558 559 if (fobj) 560 shared_count = fobj->shared_count; 561 562 for (i = 0; !fence && i < shared_count; ++i) { 563 struct dma_fence *lfence = rcu_dereference(fobj->shared[i]); 564 565 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, 566 &lfence->flags)) 567 continue; 568 569 if (!dma_fence_get_rcu(lfence)) 570 goto unlock_retry; 571 572 if (dma_fence_is_signaled(lfence)) { 573 dma_fence_put(lfence); 574 continue; 575 } 576 577 fence = lfence; 578 break; 579 } 580 } 581 582 rcu_read_unlock(); 583 if (fence) { 584 if (read_seqcount_retry(&obj->seq, seq)) { 585 dma_fence_put(fence); 586 goto retry; 587 } 588 589 ret = dma_fence_wait_timeout(fence, intr, ret); 590 dma_fence_put(fence); 591 if (ret > 0 && wait_all && (i + 1 < shared_count)) 592 goto retry; 593 } 594 return ret; 595 596 unlock_retry: 597 rcu_read_unlock(); 598 goto retry; 599 } 600 EXPORT_SYMBOL_GPL(dma_resv_wait_timeout_rcu); 601 602 603 static inline int dma_resv_test_signaled_single(struct dma_fence *passed_fence) 604 { 605 struct dma_fence *fence, *lfence = passed_fence; 606 int ret = 1; 607 608 if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &lfence->flags)) { 609 fence = dma_fence_get_rcu(lfence); 610 if (!fence) 611 return -1; 612 613 ret = !!dma_fence_is_signaled(fence); 614 dma_fence_put(fence); 615 } 616 return ret; 617 } 618 619 /** 620 * dma_resv_test_signaled_rcu - Test if a reservation object's 621 * fences have been signaled. 622 * @obj: the reservation object 623 * @test_all: if true, test all fences, otherwise only test the exclusive 624 * fence 625 * 626 * RETURNS 627 * true if all fences signaled, else false 628 */ 629 bool dma_resv_test_signaled_rcu(struct dma_resv *obj, bool test_all) 630 { 631 unsigned seq, shared_count; 632 int ret; 633 634 rcu_read_lock(); 635 retry: 636 ret = true; 637 shared_count = 0; 638 seq = read_seqcount_begin(&obj->seq); 639 640 if (test_all) { 641 unsigned i; 642 643 struct dma_resv_list *fobj = rcu_dereference(obj->fence); 644 645 if (fobj) 646 shared_count = fobj->shared_count; 647 648 for (i = 0; i < shared_count; ++i) { 649 struct dma_fence *fence = rcu_dereference(fobj->shared[i]); 650 651 ret = dma_resv_test_signaled_single(fence); 652 if (ret < 0) 653 goto retry; 654 else if (!ret) 655 break; 656 } 657 658 if (read_seqcount_retry(&obj->seq, seq)) 659 goto retry; 660 } 661 662 if (!shared_count) { 663 struct dma_fence *fence_excl = rcu_dereference(obj->fence_excl); 664 665 if (fence_excl) { 666 ret = dma_resv_test_signaled_single(fence_excl); 667 if (ret < 0) 668 goto retry; 669 670 if (read_seqcount_retry(&obj->seq, seq)) 671 goto retry; 672 } 673 } 674 675 rcu_read_unlock(); 676 return ret; 677 } 678 EXPORT_SYMBOL_GPL(dma_resv_test_signaled_rcu); 679