diff options
| -rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo.c | 47 | ||||
| -rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 30 |
2 files changed, 77 insertions, 0 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index e8e4814b1295..4dd6f9e77a7d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -310,6 +310,53 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, | |||
| 310 | return ret; | 310 | return ret; |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo, | ||
| 314 | bool interruptible, uint32_t sequence) | ||
| 315 | { | ||
| 316 | bool wake_up = false; | ||
| 317 | int ret; | ||
| 318 | |||
| 319 | while (unlikely(atomic_xchg(&bo->reserved, 1) != 0)) { | ||
| 320 | WARN_ON(bo->seq_valid && sequence == bo->val_seq); | ||
| 321 | |||
| 322 | ret = ttm_bo_wait_unreserved(bo, interruptible); | ||
| 323 | |||
| 324 | if (unlikely(ret)) | ||
| 325 | return ret; | ||
| 326 | } | ||
| 327 | |||
| 328 | if ((bo->val_seq - sequence < (1 << 31)) || !bo->seq_valid) | ||
| 329 | wake_up = true; | ||
| 330 | |||
| 331 | /** | ||
| 332 | * Wake up waiters that may need to recheck for deadlock, | ||
| 333 | * if we decreased the sequence number. | ||
| 334 | */ | ||
| 335 | bo->val_seq = sequence; | ||
| 336 | bo->seq_valid = true; | ||
| 337 | if (wake_up) | ||
| 338 | wake_up_all(&bo->event_queue); | ||
| 339 | |||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | |||
| 343 | int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, | ||
| 344 | bool interruptible, uint32_t sequence) | ||
| 345 | { | ||
| 346 | struct ttm_bo_global *glob = bo->glob; | ||
| 347 | int put_count, ret; | ||
| 348 | |||
| 349 | ret = ttm_bo_reserve_slowpath_nolru(bo, interruptible, sequence); | ||
| 350 | if (likely(!ret)) { | ||
| 351 | spin_lock(&glob->lru_lock); | ||
| 352 | put_count = ttm_bo_del_from_lru(bo); | ||
| 353 | spin_unlock(&glob->lru_lock); | ||
| 354 | ttm_bo_list_ref_sub(bo, put_count, true); | ||
| 355 | } | ||
| 356 | return ret; | ||
| 357 | } | ||
| 358 | EXPORT_SYMBOL(ttm_bo_reserve_slowpath); | ||
| 359 | |||
| 313 | void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo) | 360 | void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo) |
| 314 | { | 361 | { |
| 315 | ttm_bo_add_to_lru(bo); | 362 | ttm_bo_add_to_lru(bo); |
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 6fff43222e20..5af71af6bf88 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
| @@ -821,6 +821,36 @@ extern int ttm_bo_reserve(struct ttm_buffer_object *bo, | |||
| 821 | bool interruptible, | 821 | bool interruptible, |
| 822 | bool no_wait, bool use_sequence, uint32_t sequence); | 822 | bool no_wait, bool use_sequence, uint32_t sequence); |
| 823 | 823 | ||
| 824 | /** | ||
| 825 | * ttm_bo_reserve_slowpath_nolru: | ||
| 826 | * @bo: A pointer to a struct ttm_buffer_object. | ||
| 827 | * @interruptible: Sleep interruptible if waiting. | ||
| 828 | * @sequence: Set (@bo)->sequence to this value after lock | ||
| 829 | * | ||
| 830 | * This is called after ttm_bo_reserve returns -EAGAIN and we backed off | ||
| 831 | * from all our other reservations. Because there are no other reservations | ||
| 832 | * held by us, this function cannot deadlock any more. | ||
| 833 | * | ||
| 834 | * Will not remove reserved buffers from the lru lists. | ||
| 835 | * Otherwise identical to ttm_bo_reserve_slowpath. | ||
| 836 | */ | ||
| 837 | extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo, | ||
| 838 | bool interruptible, | ||
| 839 | uint32_t sequence); | ||
| 840 | |||
| 841 | |||
| 842 | /** | ||
| 843 | * ttm_bo_reserve_slowpath: | ||
| 844 | * @bo: A pointer to a struct ttm_buffer_object. | ||
| 845 | * @interruptible: Sleep interruptible if waiting. | ||
| 846 | * @sequence: Set (@bo)->sequence to this value after lock | ||
| 847 | * | ||
| 848 | * This is called after ttm_bo_reserve returns -EAGAIN and we backed off | ||
| 849 | * from all our other reservations. Because there are no other reservations | ||
| 850 | * held by us, this function cannot deadlock any more. | ||
| 851 | */ | ||
| 852 | extern int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, | ||
| 853 | bool interruptible, uint32_t sequence); | ||
| 824 | 854 | ||
| 825 | /** | 855 | /** |
| 826 | * ttm_bo_reserve_nolru: | 856 | * ttm_bo_reserve_nolru: |
