Commit aa35071c authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/ttm: optionally move duplicates to a separate list

This patch adds an optional list_head parameter to ttm_eu_reserve_buffers.
If specified duplicates in the execbuf list are no longer reported as errors,
but moved to this list instead.
Reviewed-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5e5c21ca
...@@ -264,7 +264,8 @@ int qxl_release_reserve_list(struct qxl_release *release, bool no_intr) ...@@ -264,7 +264,8 @@ int qxl_release_reserve_list(struct qxl_release *release, bool no_intr)
if (list_is_singular(&release->bos)) if (list_is_singular(&release->bos))
return 0; return 0;
ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos, !no_intr); ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos,
!no_intr, NULL);
if (ret) if (ret)
return ret; return ret;
......
...@@ -564,7 +564,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, ...@@ -564,7 +564,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev,
if (!vm_bos) if (!vm_bos)
return; return;
r = ttm_eu_reserve_buffers(&ticket, &list, true); r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
if (r) if (r)
goto error_free; goto error_free;
......
...@@ -508,7 +508,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev, ...@@ -508,7 +508,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
u64 bytes_moved = 0, initial_bytes_moved; u64 bytes_moved = 0, initial_bytes_moved;
u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev); u64 bytes_moved_threshold = radeon_bo_get_threshold_for_moves(rdev);
r = ttm_eu_reserve_buffers(ticket, head, true); r = ttm_eu_reserve_buffers(ticket, head, true, NULL);
if (unlikely(r != 0)) { if (unlikely(r != 0)) {
return r; return r;
} }
......
...@@ -93,7 +93,8 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation); ...@@ -93,7 +93,8 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation);
*/ */
int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
struct list_head *list, bool intr) struct list_head *list, bool intr,
struct list_head *dups)
{ {
struct ttm_bo_global *glob; struct ttm_bo_global *glob;
struct ttm_validate_buffer *entry; struct ttm_validate_buffer *entry;
...@@ -117,6 +118,13 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, ...@@ -117,6 +118,13 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
__ttm_bo_unreserve(bo); __ttm_bo_unreserve(bo);
ret = -EBUSY; ret = -EBUSY;
} else if (ret == -EALREADY && dups) {
struct ttm_validate_buffer *safe = entry;
entry = list_prev_entry(entry, head);
list_del(&safe->head);
list_add(&safe->head, dups);
continue;
} }
if (!ret) { if (!ret) {
......
...@@ -2487,7 +2487,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, ...@@ -2487,7 +2487,8 @@ int vmw_execbuf_process(struct drm_file *file_priv,
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_err_nores; goto out_err_nores;
ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, true); ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes,
true, NULL);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_err; goto out_err;
...@@ -2677,7 +2678,8 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, ...@@ -2677,7 +2678,8 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
query_val.shared = false; query_val.shared = false;
list_add_tail(&query_val.head, &validate_list); list_add_tail(&query_val.head, &validate_list);
ret = ttm_eu_reserve_buffers(&ticket, &validate_list, false); ret = ttm_eu_reserve_buffers(&ticket, &validate_list,
false, NULL);
if (unlikely(ret != 0)) { if (unlikely(ret != 0)) {
vmw_execbuf_unpin_panic(dev_priv); vmw_execbuf_unpin_panic(dev_priv);
goto out_no_reserve; goto out_no_reserve;
......
...@@ -1222,7 +1222,7 @@ vmw_resource_check_buffer(struct vmw_resource *res, ...@@ -1222,7 +1222,7 @@ vmw_resource_check_buffer(struct vmw_resource *res,
val_buf->bo = ttm_bo_reference(&res->backup->base); val_buf->bo = ttm_bo_reference(&res->backup->base);
val_buf->shared = false; val_buf->shared = false;
list_add_tail(&val_buf->head, &val_list); list_add_tail(&val_buf->head, &val_list);
ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible); ret = ttm_eu_reserve_buffers(NULL, &val_list, interruptible, NULL);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_no_reserve; goto out_no_reserve;
......
...@@ -68,6 +68,7 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, ...@@ -68,6 +68,7 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
* non-blocking reserves should be tried. * non-blocking reserves should be tried.
* @list: thread private list of ttm_validate_buffer structs. * @list: thread private list of ttm_validate_buffer structs.
* @intr: should the wait be interruptible * @intr: should the wait be interruptible
* @dups: [out] optional list of duplicates.
* *
* Tries to reserve bos pointed to by the list entries for validation. * Tries to reserve bos pointed to by the list entries for validation.
* If the function returns 0, all buffers are marked as "unfenced", * If the function returns 0, all buffers are marked as "unfenced",
...@@ -83,6 +84,11 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, ...@@ -83,6 +84,11 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
* calling process receives a signal while waiting. In that case, no * calling process receives a signal while waiting. In that case, no
* buffers on the list will be reserved upon return. * buffers on the list will be reserved upon return.
* *
* If dups is non NULL all buffers already reserved by the current thread
* (e.g. duplicates) are added to this list, otherwise -EALREADY is returned
* on the first already reserved buffer and all buffers from the list are
* unreserved again.
*
* Buffers reserved by this function should be unreserved by * Buffers reserved by this function should be unreserved by
* a call to either ttm_eu_backoff_reservation() or * a call to either ttm_eu_backoff_reservation() or
* ttm_eu_fence_buffer_objects() when command submission is complete or * ttm_eu_fence_buffer_objects() when command submission is complete or
...@@ -90,7 +96,8 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket, ...@@ -90,7 +96,8 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
*/ */
extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
struct list_head *list, bool intr); struct list_head *list, bool intr,
struct list_head *dups);
/** /**
* function ttm_eu_fence_buffer_objects. * function ttm_eu_fence_buffer_objects.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment