Commit b8e902f24fdd16c4373ddc37a4e150c4afe9c6db

Authored by Thomas Hellstrom
Committed by Dave Airlie
1 parent 7bc17a7837

drm/ttm: Fix a theoretical race in ttm_bo_cleanup_refs()

In theory, that function could release the lru lock between
checking for bo on ddestroy list and a successful reserve if the bo
was already reserved, and the function was called with waiting reserves
allowed.
However, all current reservers of a bo on the ddestroy list would
atomically take the bo off the list after a successful reserve so this
race should not have been hit, so no need to backport for stable.

This patch also fixes a case found by Maarten Lankhorst where
ttm_mem_evict_first called with no_wait_gpu would incorrectly
spin waiting for bo idle if trying to evict a busy buffer that
also sits on the ddestroy list.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

Showing 1 changed file with 12 additions and 8 deletions Side-by-side Diff

drivers/gpu/drm/ttm/ttm_bo.c
... ... @@ -580,6 +580,7 @@
580 580 if (unlikely(ret != 0))
581 581 return ret;
582 582  
  583 +retry_reserve:
583 584 spin_lock(&glob->lru_lock);
584 585  
585 586 if (unlikely(list_empty(&bo->ddestroy))) {
586 587  
587 588  
588 589  
... ... @@ -587,14 +588,20 @@
587 588 return 0;
588 589 }
589 590  
590   - ret = ttm_bo_reserve_locked(bo, interruptible,
591   - no_wait_reserve, false, 0);
  591 + ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
592 592  
593   - if (unlikely(ret != 0)) {
  593 + if (unlikely(ret == -EBUSY)) {
594 594 spin_unlock(&glob->lru_lock);
595   - return ret;
  595 + if (likely(!no_wait_reserve))
  596 + ret = ttm_bo_wait_unreserved(bo, interruptible);
  597 + if (unlikely(ret != 0))
  598 + return ret;
  599 +
  600 + goto retry_reserve;
596 601 }
597 602  
  603 + BUG_ON(ret != 0);
  604 +
598 605 /**
599 606 * We can re-check for sync object without taking
600 607 * the bo::lock since setting the sync object requires
... ... @@ -811,10 +818,7 @@
811 818 no_wait_reserve, no_wait_gpu);
812 819 kref_put(&bo->list_kref, ttm_bo_release_list);
813 820  
814   - if (likely(ret == 0 || ret == -ERESTARTSYS))
815   - return ret;
816   -
817   - goto retry;
  821 + return ret;
818 822 }
819 823  
820 824 ret = ttm_bo_reserve_locked(bo, false, true, false, 0);