drm/ttm/amdgpu: consolidate ttm reserve paths
Drop the WARN_ON and consolidate the two paths into one. Use the consolidate slowpath in the execbuf utils code. Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200804025632.3868079-6-airlied@gmail.com
This commit is contained in:
Родитель
9c4cbb3a66
Коммит
46bca88bbd
|
@ -160,7 +160,7 @@ static inline int amdgpu_bo_reserve(struct amdgpu_bo *bo, bool no_intr)
|
|||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
int r;
|
||||
|
||||
r = __ttm_bo_reserve(&bo->tbo, !no_intr, false, NULL);
|
||||
r = ttm_bo_reserve(&bo->tbo, !no_intr, false, NULL);
|
||||
if (unlikely(r != 0)) {
|
||||
if (r != -ERESTARTSYS)
|
||||
dev_err(adev->dev, "%p reserve failed\n", bo);
|
||||
|
|
|
@ -93,7 +93,7 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
|
|||
list_for_each_entry(entry, list, head) {
|
||||
struct ttm_buffer_object *bo = entry->bo;
|
||||
|
||||
ret = __ttm_bo_reserve(bo, intr, (ticket == NULL), ticket);
|
||||
ret = ttm_bo_reserve(bo, intr, (ticket == NULL), ticket);
|
||||
if (ret == -EALREADY && dups) {
|
||||
struct ttm_validate_buffer *safe = entry;
|
||||
entry = list_prev_entry(entry, head);
|
||||
|
@ -119,13 +119,7 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
|
|||
ttm_eu_backoff_reservation_reverse(list, entry);
|
||||
|
||||
if (ret == -EDEADLK) {
|
||||
if (intr) {
|
||||
ret = dma_resv_lock_slow_interruptible(bo->base.resv,
|
||||
ticket);
|
||||
} else {
|
||||
dma_resv_lock_slow(bo->base.resv, ticket);
|
||||
ret = 0;
|
||||
}
|
||||
ret = ttm_bo_reserve_slowpath(bo, intr, ticket);
|
||||
}
|
||||
|
||||
if (!ret && entry->num_shared)
|
||||
|
@ -133,8 +127,6 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
|
|||
entry->num_shared);
|
||||
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret == -EINTR)
|
||||
ret = -ERESTARTSYS;
|
||||
if (ticket) {
|
||||
ww_acquire_done(ticket);
|
||||
ww_acquire_fini(ticket);
|
||||
|
|
|
@ -599,29 +599,30 @@ int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible);
|
|||
void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
|
||||
|
||||
/**
|
||||
* __ttm_bo_reserve:
|
||||
* ttm_bo_reserve:
|
||||
*
|
||||
* @bo: A pointer to a struct ttm_buffer_object.
|
||||
* @interruptible: Sleep interruptible if waiting.
|
||||
* @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
|
||||
* @ticket: ticket used to acquire the ww_mutex.
|
||||
*
|
||||
* Will not remove reserved buffers from the lru lists.
|
||||
* Otherwise identical to ttm_bo_reserve.
|
||||
* Locks a buffer object for validation. (Or prevents other processes from
|
||||
* locking it for validation), while taking a number of measures to prevent
|
||||
* deadlocks.
|
||||
*
|
||||
* Returns:
|
||||
* -EDEADLK: The reservation may cause a deadlock.
|
||||
* Release all buffer reservations, wait for @bo to become unreserved and
|
||||
* try again. (only if use_sequence == 1).
|
||||
* try again.
|
||||
* -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
|
||||
* a signal. Release all buffer reservations and return to user-space.
|
||||
* -EBUSY: The function needed to sleep, but @no_wait was true
|
||||
* -EALREADY: Bo already reserved using @ticket. This error code will only
|
||||
* be returned if @use_ticket is set to true.
|
||||
*/
|
||||
static inline int __ttm_bo_reserve(struct ttm_buffer_object *bo,
|
||||
bool interruptible, bool no_wait,
|
||||
struct ww_acquire_ctx *ticket)
|
||||
static inline int ttm_bo_reserve(struct ttm_buffer_object *bo,
|
||||
bool interruptible, bool no_wait,
|
||||
struct ww_acquire_ctx *ticket)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -643,59 +644,6 @@ static inline int __ttm_bo_reserve(struct ttm_buffer_object *bo,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ttm_bo_reserve:
|
||||
*
|
||||
* @bo: A pointer to a struct ttm_buffer_object.
|
||||
* @interruptible: Sleep interruptible if waiting.
|
||||
* @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
|
||||
* @ticket: ticket used to acquire the ww_mutex.
|
||||
*
|
||||
* Locks a buffer object for validation. (Or prevents other processes from
|
||||
* locking it for validation) and removes it from lru lists, while taking
|
||||
* a number of measures to prevent deadlocks.
|
||||
*
|
||||
* Deadlocks may occur when two processes try to reserve multiple buffers in
|
||||
* different order, either by will or as a result of a buffer being evicted
|
||||
* to make room for a buffer already reserved. (Buffers are reserved before
|
||||
* they are evicted). The following algorithm prevents such deadlocks from
|
||||
* occurring:
|
||||
* Processes attempting to reserve multiple buffers other than for eviction,
|
||||
* (typically execbuf), should first obtain a unique 32-bit
|
||||
* validation sequence number,
|
||||
* and call this function with @use_ticket == 1 and @ticket->stamp == the unique
|
||||
* sequence number. If upon call of this function, the buffer object is already
|
||||
* reserved, the validation sequence is checked against the validation
|
||||
* sequence of the process currently reserving the buffer,
|
||||
* and if the current validation sequence is greater than that of the process
|
||||
* holding the reservation, the function returns -EDEADLK. Otherwise it sleeps
|
||||
* waiting for the buffer to become unreserved, after which it retries
|
||||
* reserving.
|
||||
* The caller should, when receiving an -EDEADLK error
|
||||
* release all its buffer reservations, wait for @bo to become unreserved, and
|
||||
* then rerun the validation with the same validation sequence. This procedure
|
||||
* will always guarantee that the process with the lowest validation sequence
|
||||
* will eventually succeed, preventing both deadlocks and starvation.
|
||||
*
|
||||
* Returns:
|
||||
* -EDEADLK: The reservation may cause a deadlock.
|
||||
* Release all buffer reservations, wait for @bo to become unreserved and
|
||||
* try again. (only if use_sequence == 1).
|
||||
* -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
|
||||
* a signal. Release all buffer reservations and return to user-space.
|
||||
* -EBUSY: The function needed to sleep, but @no_wait was true
|
||||
* -EALREADY: Bo already reserved using @ticket. This error code will only
|
||||
* be returned if @use_ticket is set to true.
|
||||
*/
|
||||
static inline int ttm_bo_reserve(struct ttm_buffer_object *bo,
|
||||
bool interruptible, bool no_wait,
|
||||
struct ww_acquire_ctx *ticket)
|
||||
{
|
||||
WARN_ON(!kref_read(&bo->kref));
|
||||
|
||||
return __ttm_bo_reserve(bo, interruptible, no_wait, ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* ttm_bo_reserve_slowpath:
|
||||
* @bo: A pointer to a struct ttm_buffer_object.
|
||||
|
@ -710,20 +658,15 @@ static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
|
|||
bool interruptible,
|
||||
struct ww_acquire_ctx *ticket)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
WARN_ON(!kref_read(&bo->kref));
|
||||
|
||||
if (interruptible)
|
||||
ret = dma_resv_lock_slow_interruptible(bo->base.resv,
|
||||
ticket);
|
||||
else
|
||||
dma_resv_lock_slow(bo->base.resv, ticket);
|
||||
|
||||
if (ret == -EINTR)
|
||||
ret = -ERESTARTSYS;
|
||||
|
||||
return ret;
|
||||
if (interruptible) {
|
||||
int ret = dma_resv_lock_slow_interruptible(bo->base.resv,
|
||||
ticket);
|
||||
if (ret == -EINTR)
|
||||
ret = -ERESTARTSYS;
|
||||
return ret;
|
||||
}
|
||||
dma_resv_lock_slow(bo->base.resv, ticket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче