aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c171
1 files changed, 107 insertions, 64 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 4a73f401644d..a1cb783c7131 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -455,100 +455,123 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
455 wake_up_all(&bo->event_queue); 455 wake_up_all(&bo->event_queue);
456} 456}
457 457
458 458static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
459/**
460 * If bo idle, remove from delayed- and lru lists, and unref.
461 * If not idle, and already on delayed list, do nothing.
462 * If not idle, and not on delayed list, put on delayed list,
463 * up the list_kref and schedule a delayed list check.
464 */
465
466static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
467{ 459{
468 struct ttm_bo_device *bdev = bo->bdev; 460 struct ttm_bo_device *bdev = bo->bdev;
469 struct ttm_bo_global *glob = bo->glob; 461 struct ttm_bo_global *glob = bo->glob;
470 struct ttm_bo_driver *driver = bdev->driver; 462 struct ttm_bo_driver *driver;
463 void *sync_obj;
464 void *sync_obj_arg;
465 int put_count;
471 int ret; 466 int ret;
472 467
473 spin_lock(&bo->lock); 468 spin_lock(&bo->lock);
474retry: 469 (void) ttm_bo_wait(bo, false, false, true);
475 (void) ttm_bo_wait(bo, false, false, !remove_all);
476
477 if (!bo->sync_obj) { 470 if (!bo->sync_obj) {
478 int put_count;
479
480 spin_unlock(&bo->lock);
481 471
482 spin_lock(&glob->lru_lock); 472 spin_lock(&glob->lru_lock);
483 ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0);
484 473
485 /** 474 /**
486 * Someone else has the object reserved. Bail and retry. 475 * Lock inversion between bo::reserve and bo::lock here,
476 * but that's OK, since we're only trylocking.
487 */ 477 */
488 478
489 if (unlikely(ret == -EBUSY)) { 479 ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
490 spin_unlock(&glob->lru_lock);
491 spin_lock(&bo->lock);
492 goto requeue;
493 }
494
495 /**
496 * We can re-check for sync object without taking
497 * the bo::lock since setting the sync object requires
498 * also bo::reserved. A busy object at this point may
499 * be caused by another thread starting an accelerated
500 * eviction.
501 */
502 480
503 if (unlikely(bo->sync_obj)) { 481 if (unlikely(ret == -EBUSY))
504 atomic_set(&bo->reserved, 0); 482 goto queue;
505 wake_up_all(&bo->event_queue);
506 spin_unlock(&glob->lru_lock);
507 spin_lock(&bo->lock);
508 if (remove_all)
509 goto retry;
510 else
511 goto requeue;
512 }
513 483
484 spin_unlock(&bo->lock);
514 put_count = ttm_bo_del_from_lru(bo); 485 put_count = ttm_bo_del_from_lru(bo);
515 486
516 if (!list_empty(&bo->ddestroy)) {
517 list_del_init(&bo->ddestroy);
518 ++put_count;
519 }
520 spin_unlock(&glob->lru_lock); 487 spin_unlock(&glob->lru_lock);
521 ttm_bo_cleanup_memtype_use(bo); 488 ttm_bo_cleanup_memtype_use(bo);
522 489
523 while (put_count--) 490 while (put_count--)
524 kref_put(&bo->list_kref, ttm_bo_ref_bug); 491 kref_put(&bo->list_kref, ttm_bo_ref_bug);
525 492
526 return 0; 493 return;
494 } else {
495 spin_lock(&glob->lru_lock);
527 } 496 }
528requeue: 497queue:
498 sync_obj = bo->sync_obj;
499 sync_obj_arg = bo->sync_obj_arg;
500 driver = bdev->driver;
501
502 kref_get(&bo->list_kref);
503 list_add_tail(&bo->ddestroy, &bdev->ddestroy);
504 spin_unlock(&glob->lru_lock);
505 spin_unlock(&bo->lock);
506
507 if (sync_obj)
508 driver->sync_obj_flush(sync_obj, sync_obj_arg);
509 schedule_delayed_work(&bdev->wq,
510 ((HZ / 100) < 1) ? 1 : HZ / 100);
511}
512
513/**
514 * function ttm_bo_cleanup_refs
515 * If bo idle, remove from delayed- and lru lists, and unref.
516 * If not idle, do nothing.
517 *
518 * @interruptible Any sleeps should occur interruptibly.
519 * @no_wait_reserve Never wait for reserve. Return -EBUSY instead.
520 * @no_wait_gpu Never wait for gpu. Return -EBUSY instead.
521 */
522
523static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo,
524 bool interruptible,
525 bool no_wait_reserve,
526 bool no_wait_gpu)
527{
528 struct ttm_bo_global *glob = bo->glob;
529 int put_count;
530 int ret = 0;
531
532retry:
533 spin_lock(&bo->lock);
534 ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu);
535 spin_unlock(&bo->lock);
536
537 if (unlikely(ret != 0))
538 return ret;
539
529 spin_lock(&glob->lru_lock); 540 spin_lock(&glob->lru_lock);
530 if (list_empty(&bo->ddestroy)) { 541 ret = ttm_bo_reserve_locked(bo, interruptible,
531 void *sync_obj = bo->sync_obj; 542 no_wait_reserve, false, 0);
532 void *sync_obj_arg = bo->sync_obj_arg;
533 543
534 kref_get(&bo->list_kref); 544 if (unlikely(ret != 0) || list_empty(&bo->ddestroy)) {
535 list_add_tail(&bo->ddestroy, &bdev->ddestroy);
536 spin_unlock(&glob->lru_lock); 545 spin_unlock(&glob->lru_lock);
537 spin_unlock(&bo->lock); 546 return ret;
547 }
538 548
539 if (sync_obj) 549 /**
540 driver->sync_obj_flush(sync_obj, sync_obj_arg); 550 * We can re-check for sync object without taking
541 schedule_delayed_work(&bdev->wq, 551 * the bo::lock since setting the sync object requires
542 ((HZ / 100) < 1) ? 1 : HZ / 100); 552 * also bo::reserved. A busy object at this point may
543 ret = 0; 553 * be caused by another thread recently starting an accelerated
554 * eviction.
555 */
544 556
545 } else { 557 if (unlikely(bo->sync_obj)) {
558 atomic_set(&bo->reserved, 0);
559 wake_up_all(&bo->event_queue);
546 spin_unlock(&glob->lru_lock); 560 spin_unlock(&glob->lru_lock);
547 spin_unlock(&bo->lock); 561 goto retry;
548 ret = -EBUSY;
549 } 562 }
550 563
551 return ret; 564 put_count = ttm_bo_del_from_lru(bo);
565 list_del_init(&bo->ddestroy);
566 ++put_count;
567
568 spin_unlock(&glob->lru_lock);
569 ttm_bo_cleanup_memtype_use(bo);
570
571 while (put_count--)
572 kref_put(&bo->list_kref, ttm_bo_ref_bug);
573
574 return 0;
552} 575}
553 576
554/** 577/**
@@ -580,7 +603,8 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
580 } 603 }
581 604
582 spin_unlock(&glob->lru_lock); 605 spin_unlock(&glob->lru_lock);
583 ret = ttm_bo_cleanup_refs(entry, remove_all); 606 ret = ttm_bo_cleanup_refs(entry, false, !remove_all,
607 !remove_all);
584 kref_put(&entry->list_kref, ttm_bo_release_list); 608 kref_put(&entry->list_kref, ttm_bo_release_list);
585 entry = nentry; 609 entry = nentry;
586 610
@@ -623,7 +647,7 @@ static void ttm_bo_release(struct kref *kref)
623 bo->vm_node = NULL; 647 bo->vm_node = NULL;
624 } 648 }
625 write_unlock(&bdev->vm_lock); 649 write_unlock(&bdev->vm_lock);
626 ttm_bo_cleanup_refs(bo, false); 650 ttm_bo_cleanup_refs_or_queue(bo);
627 kref_put(&bo->list_kref, ttm_bo_release_list); 651 kref_put(&bo->list_kref, ttm_bo_release_list);
628 write_lock(&bdev->vm_lock); 652 write_lock(&bdev->vm_lock);
629} 653}
@@ -731,6 +755,18 @@ retry:
731 bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru); 755 bo = list_first_entry(&man->lru, struct ttm_buffer_object, lru);
732 kref_get(&bo->list_kref); 756 kref_get(&bo->list_kref);
733 757
758 if (!list_empty(&bo->ddestroy)) {
759 spin_unlock(&glob->lru_lock);
760 ret = ttm_bo_cleanup_refs(bo, interruptible,
761 no_wait_reserve, no_wait_gpu);
762 kref_put(&bo->list_kref, ttm_bo_release_list);
763
764 if (likely(ret == 0 || ret == -ERESTARTSYS))
765 return ret;
766
767 goto retry;
768 }
769
734 ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0); 770 ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0);
735 771
736 if (unlikely(ret == -EBUSY)) { 772 if (unlikely(ret == -EBUSY)) {
@@ -1754,6 +1790,13 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
1754 struct ttm_buffer_object, swap); 1790 struct ttm_buffer_object, swap);
1755 kref_get(&bo->list_kref); 1791 kref_get(&bo->list_kref);
1756 1792
1793 if (!list_empty(&bo->ddestroy)) {
1794 spin_unlock(&glob->lru_lock);
1795 (void) ttm_bo_cleanup_refs(bo, false, false, false);
1796 kref_put(&bo->list_kref, ttm_bo_release_list);
1797 continue;
1798 }
1799
1757 /** 1800 /**
1758 * Reserve buffer. Since we unlock while sleeping, we need 1801 * Reserve buffer. Since we unlock while sleeping, we need
1759 * to re-check that nobody removed us from the swap-list while 1802 * to re-check that nobody removed us from the swap-list while