@@ -465,7 +465,7 @@ struct amdgpu_cs_parser {
struct drm_sched_entity *entity;
/* buffer objects */
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct amdgpu_bo_list *bo_list;
struct amdgpu_mn *mn;
struct amdgpu_bo_list_entry vm_pd;
@@ -540,7 +540,7 @@ struct bo_vm_reservation_context {
struct amdgpu_bo_list_entry kfd_bo; /* BO list entry for the KFD BO */
unsigned int n_vms; /* Number of VMs reserved */
struct amdgpu_bo_list_entry *vm_pd; /* Array of VM BO list entries */
- struct ww_acquire_ctx ticket; /* Reservation ticket */
+ struct dma_resv_ctx ticket; /* Reservation ticket */
struct list_head list, duplicates; /* BO lists */
struct amdgpu_sync *sync; /* Pointer to sync object */
bool reserved; /* Whether BOs are reserved */
@@ -1760,7 +1760,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
{
struct amdgpu_bo_list_entry *pd_bo_list_entries;
struct list_head resv_list, duplicates;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct amdgpu_sync sync;
struct amdgpu_vm *peer_vm;
@@ -1325,7 +1325,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
amdgpu_job_free_resources(job);
trace_amdgpu_cs_ioctl(job);
- amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket);
+ amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket.base);
priority = job->base.s_priority;
drm_sched_entity_push_job(&job->base, entity);
@@ -1729,7 +1729,7 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
*map = mapping;
/* Double check that the BO is reserved by this CS */
- if (dma_resv_locking_ctx((*bo)->tbo.base.resv) != &parser->ticket)
+ if (dma_resv_locking_ctx((*bo)->tbo.base.resv) != &parser->ticket.base)
return -EINVAL;
if (!((*bo)->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) {
@@ -66,7 +66,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va,
uint64_t csa_addr, uint32_t size)
{
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct list_head list;
struct amdgpu_bo_list_entry pd;
struct ttm_validate_buffer csa_tv;
@@ -162,7 +162,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
struct amdgpu_bo_list_entry vm_pd;
struct list_head list, duplicates;
struct ttm_validate_buffer tv;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct amdgpu_bo_va *bo_va;
int r;
@@ -549,7 +549,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
struct amdgpu_bo_va *bo_va;
struct amdgpu_bo_list_entry vm_pd;
struct ttm_validate_buffer tv;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct list_head list, duplicates;
uint64_t va_flags;
int r = 0;
@@ -4416,7 +4416,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
struct list_head list;
struct ttm_validate_buffer tv;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
uint64_t tiling_flags;
uint32_t domain;
int r;
@@ -154,7 +154,7 @@ struct qxl_release {
struct qxl_bo *release_bo;
uint32_t release_offset;
uint32_t surface_release_id;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct list_head bos;
};
@@ -463,6 +463,6 @@ void qxl_release_fence_buffer_objects(struct qxl_release *release)
dma_resv_unlock(bo->base.resv);
}
spin_unlock(&glob->lru_lock);
- ww_acquire_fini(&release->ticket);
+ dma_resv_ctx_fini(&release->ticket);
}
@@ -1083,7 +1083,7 @@ struct radeon_cs_parser {
u32 cs_flags;
u32 ring;
s32 priority;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
};
static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
@@ -549,7 +549,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev,
{
struct ttm_validate_buffer tv, *entry;
struct radeon_bo_list *vm_bos;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct list_head list;
unsigned domain;
int r;
@@ -531,7 +531,7 @@ static u64 radeon_bo_get_threshold_for_moves(struct radeon_device *rdev)
}
int radeon_bo_list_validate(struct radeon_device *rdev,
- struct ww_acquire_ctx *ticket,
+ struct dma_resv_ctx *ticket,
struct list_head *head, int ring)
{
struct ttm_operation_ctx ctx = { true, false };
@@ -141,7 +141,7 @@ extern void radeon_bo_force_delete(struct radeon_device *rdev);
extern int radeon_bo_init(struct radeon_device *rdev);
extern void radeon_bo_fini(struct radeon_device *rdev);
extern int radeon_bo_list_validate(struct radeon_device *rdev,
- struct ww_acquire_ctx *ticket,
+ struct dma_resv_ctx *ticket,
struct list_head *head, int ring);
extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
u32 tiling_flags, u32 pitch);
@@ -33,16 +33,6 @@
#include <linux/sched.h>
#include <linux/module.h>
-static void ttm_eu_backoff_reservation_reverse(struct list_head *list,
- struct ttm_validate_buffer *entry)
-{
- list_for_each_entry_continue_reverse(entry, list, head) {
- struct ttm_buffer_object *bo = entry->bo;
-
- dma_resv_unlock(bo->base.resv);
- }
-}
-
static void ttm_eu_del_from_lru_locked(struct list_head *list)
{
struct ttm_validate_buffer *entry;
@@ -53,7 +43,7 @@ static void ttm_eu_del_from_lru_locked(struct list_head *list)
}
}
-void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
+void ttm_eu_backoff_reservation(struct dma_resv_ctx *ticket,
struct list_head *list)
{
struct ttm_validate_buffer *entry;
@@ -71,12 +61,15 @@ void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
if (list_empty(&bo->lru))
ttm_bo_add_to_lru(bo);
- dma_resv_unlock(bo->base.resv);
+ if (!ticket)
+ dma_resv_unlock(bo->base.resv);
}
spin_unlock(&glob->lru_lock);
- if (ticket)
- ww_acquire_fini(ticket);
+ if (ticket) {
+ dma_resv_ctx_unlock_all(ticket);
+ dma_resv_ctx_fini(ticket);
+ }
}
EXPORT_SYMBOL(ttm_eu_backoff_reservation);
@@ -92,12 +85,12 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation);
* buffers in different orders.
*/
-int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
+int ttm_eu_reserve_buffers(struct dma_resv_ctx *ticket,
struct list_head *list, bool intr,
struct list_head *dups, bool del_lru)
{
- struct ttm_bo_global *glob;
struct ttm_validate_buffer *entry;
+ struct ttm_bo_global *glob;
int ret;
if (list_empty(list))
@@ -107,70 +100,46 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
glob = entry->bo->bdev->glob;
if (ticket)
- ww_acquire_init(ticket, &reservation_ww_class);
+ dma_resv_ctx_init(ticket);
+retry:
list_for_each_entry(entry, list, head) {
struct ttm_buffer_object *bo = entry->bo;
- ret = __ttm_bo_reserve(bo, intr, (ticket == NULL), ticket);
- if (!ret && unlikely(atomic_read(&bo->cpu_writers) > 0)) {
- dma_resv_unlock(bo->base.resv);
+ if (likely(ticket)) {
+ ret = dma_resv_ctx_lock(ticket, bo->base.resv, intr);
+ if (ret == -EDEADLK)
+ goto retry;
+ } else {
+ ret = dma_resv_trylock(bo->base.resv) ? 0 : -EBUSY;
+ }
+ if (!ret && unlikely(atomic_read(&bo->cpu_writers) > 0)) {
+ if (!ticket)
+ dma_resv_unlock(bo->base.resv);
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 (!entry->num_shared)
- continue;
+ if (unlikely(ret))
+ goto error;
- ret = dma_resv_reserve_shared(bo->base.resv,
- entry->num_shared);
- if (!ret)
- continue;
- }
-
- /* uh oh, we lost out, drop every reservation and try
- * to only reserve this buffer, then start over if
- * this succeeds.
- */
- 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;
- }
- }
+ if (!entry->num_shared)
+ continue;
- if (!ret && entry->num_shared)
- ret = dma_resv_reserve_shared(bo->base.resv,
- entry->num_shared);
-
- if (unlikely(ret != 0)) {
- if (ret == -EINTR)
- ret = -ERESTARTSYS;
- if (ticket) {
- ww_acquire_done(ticket);
- ww_acquire_fini(ticket);
- }
- return ret;
+ ret = dma_resv_reserve_shared(bo->base.resv, entry->num_shared);
+ if (unlikely(ret)) {
+ if (!ticket)
+ dma_resv_unlock(bo->base.resv);
+ goto error;
}
-
- /* move this item to the front of the list,
- * forces correct iteration of the loop without keeping track
- */
- list_del(&entry->head);
- list_add(&entry->head, list);
}
if (del_lru) {
@@ -179,10 +148,23 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
spin_unlock(&glob->lru_lock);
}
return 0;
+
+error:
+ if (ret == -EINTR)
+ ret = -ERESTARTSYS;
+ if (ticket) {
+ dma_resv_ctx_unlock_all(ticket);
+ dma_resv_ctx_done(ticket);
+ dma_resv_ctx_fini(ticket);
+ } else {
+ list_for_each_entry_continue_reverse(entry, list, head)
+ dma_resv_unlock(entry->bo->base.resv);
+ }
+ return ret;
}
EXPORT_SYMBOL(ttm_eu_reserve_buffers);
-void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
+void ttm_eu_fence_buffer_objects(struct dma_resv_ctx *ticket,
struct list_head *list,
struct dma_fence *fence)
{
@@ -208,10 +190,13 @@ void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
ttm_bo_add_to_lru(bo);
else
ttm_bo_move_to_lru_tail(bo, NULL);
- dma_resv_unlock(bo->base.resv);
+ if (!ticket)
+ dma_resv_unlock(bo->base.resv);
}
spin_unlock(&glob->lru_lock);
- if (ticket)
- ww_acquire_fini(ticket);
+ if (ticket) {
+ dma_resv_ctx_unlock_all(ticket);
+ dma_resv_ctx_fini(ticket);
+ }
}
EXPORT_SYMBOL(ttm_eu_fence_buffer_objects);
@@ -443,7 +443,7 @@ void vmw_resource_unreserve(struct vmw_resource *res,
* reserved and validated backup buffer.
*/
static int
-vmw_resource_check_buffer(struct ww_acquire_ctx *ticket,
+vmw_resource_check_buffer(struct dma_resv_ctx *ticket,
struct vmw_resource *res,
bool interruptible,
struct ttm_validate_buffer *val_buf)
@@ -535,7 +535,7 @@ int vmw_resource_reserve(struct vmw_resource *res, bool interruptible,
* @val_buf: Backup buffer information.
*/
static void
-vmw_resource_backoff_reservation(struct ww_acquire_ctx *ticket,
+vmw_resource_backoff_reservation(struct dma_resv_ctx *ticket,
struct ttm_validate_buffer *val_buf)
{
struct list_head val_list;
@@ -558,7 +558,7 @@ vmw_resource_backoff_reservation(struct ww_acquire_ctx *ticket,
* @res: The resource to evict.
* @interruptible: Whether to wait interruptible.
*/
-static int vmw_resource_do_evict(struct ww_acquire_ctx *ticket,
+static int vmw_resource_do_evict(struct dma_resv_ctx *ticket,
struct vmw_resource *res, bool interruptible)
{
struct ttm_validate_buffer val_buf;
@@ -822,7 +822,7 @@ static void vmw_resource_evict_type(struct vmw_private *dev_priv,
struct vmw_resource *evict_res;
unsigned err_count = 0;
int ret;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
do {
spin_lock(&dev_priv->resource_lock);
@@ -77,7 +77,7 @@ struct vmw_validation_context {
struct list_head resource_ctx_list;
struct list_head bo_list;
struct list_head page_list;
- struct ww_acquire_ctx ticket;
+ struct dma_resv_ctx ticket;
struct mutex *res_mutex;
unsigned int merge_dups;
unsigned int mem_size_left;
@@ -32,6 +32,7 @@
#define _TTM_EXECBUF_UTIL_H_
#include <linux/list.h>
+#include <linux/dma-resv-ctx.h>
#include "ttm_bo_api.h"
@@ -52,20 +53,20 @@ struct ttm_validate_buffer {
/**
* function ttm_eu_backoff_reservation
*
- * @ticket: ww_acquire_ctx from reserve call
+ * @ticket: reservation_context from reserve call
* @list: thread private list of ttm_validate_buffer structs.
*
* Undoes all buffer validation reservations for bos pointed to by
* the list entries.
*/
-extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
+extern void ttm_eu_backoff_reservation(struct dma_resv_ctx *ticket,
struct list_head *list);
/**
* function ttm_eu_reserve_buffers
*
- * @ticket: [out] ww_acquire_ctx filled in by call, or NULL if only
+ * @ticket: [out] reservation_context filled in by caller, or NULL if only
* non-blocking reserves should be tried.
* @list: thread private list of ttm_validate_buffer structs.
* @intr: should the wait be interruptible
@@ -97,14 +98,14 @@ extern void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
* has failed.
*/
-extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
+extern int ttm_eu_reserve_buffers(struct dma_resv_ctx *ticket,
struct list_head *list, bool intr,
struct list_head *dups, bool del_lru);
/**
* function ttm_eu_fence_buffer_objects.
*
- * @ticket: ww_acquire_ctx from reserve call
+ * @ticket: reservation_context from reserve call
* @list: thread private list of ttm_validate_buffer structs.
* @fence: The new exclusive fence for the buffers.
*
@@ -114,7 +115,7 @@ extern int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
*
*/
-extern void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
+extern void ttm_eu_fence_buffer_objects(struct dma_resv_ctx *ticket,
struct list_head *list,
struct dma_fence *fence);
Change ttm_execbuf_util to use the new reservation context object for deadlock handling. Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 4 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- drivers/gpu/drm/qxl/qxl_drv.h | 2 +- drivers/gpu/drm/qxl/qxl_release.c | 2 +- drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_object.c | 2 +- drivers/gpu/drm/radeon/radeon_object.h | 2 +- drivers/gpu/drm/ttm/ttm_execbuf_util.c | 117 ++++++++---------- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 8 +- drivers/gpu/drm/vmwgfx/vmwgfx_validation.h | 2 +- include/drm/ttm/ttm_execbuf_util.h | 13 +- 16 files changed, 78 insertions(+), 92 deletions(-)