diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cs.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_uvd.c | 27 |
5 files changed, 29 insertions, 25 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a424949005c9..7e3fef4e6938 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -979,6 +979,7 @@ struct radeon_cs_parser { u32 cs_flags; u32 ring; s32 priority; + struct ww_acquire_ctx ticket; }; extern int radeon_cs_finish_pages(struct radeon_cs_parser *p); diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 4f6b22b799ba..13a130fb3517 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -106,7 +106,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) radeon_bo_list_add_object(&p->relocs[i].lobj, &p->validated); } - return radeon_bo_list_validate(&p->validated, p->ring); + return radeon_bo_list_validate(&p->ticket, &p->validated, p->ring); } static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority) @@ -314,15 +314,17 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) * If error is set than unvalidate buffer, otherwise just free memory * used by parsing context. **/ -static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) +static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bool backoff) { unsigned i; if (!error) { - ttm_eu_fence_buffer_objects(&parser->validated, + ttm_eu_fence_buffer_objects(&parser->ticket, + &parser->validated, parser->ib.fence); - } else { - ttm_eu_backoff_reservation(&parser->validated); + } else if (backoff) { + ttm_eu_backoff_reservation(&parser->ticket, + &parser->validated); } if (parser->relocs != NULL) { @@ -535,7 +537,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) r = radeon_cs_parser_init(&parser, data); if (r) { DRM_ERROR("Failed to initialize parser !\n"); - radeon_cs_parser_fini(&parser, r); + radeon_cs_parser_fini(&parser, r, false); up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; @@ -544,7 +546,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) { if (r != -ERESTARTSYS) DRM_ERROR("Failed to parse relocation %d!\n", r); - radeon_cs_parser_fini(&parser, r); + radeon_cs_parser_fini(&parser, r, false); up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; @@ -563,7 +565,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) goto out; } out: - radeon_cs_parser_fini(&parser, r); + radeon_cs_parser_fini(&parser, r, true); up_read(&rdev->exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 07af5a95bb62..71287bb7b433 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -349,14 +349,15 @@ void radeon_bo_list_add_object(struct radeon_bo_list *lobj, } } -int radeon_bo_list_validate(struct list_head *head, int ring) +int radeon_bo_list_validate(struct ww_acquire_ctx *ticket, + struct list_head *head, int ring) { struct radeon_bo_list *lobj; struct radeon_bo *bo; u32 domain; int r; - r = ttm_eu_reserve_buffers(head); + r = ttm_eu_reserve_buffers(ticket, head); if (unlikely(r != 0)) { return r; } diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index e2cb80a96b51..3e62a3a0fe54 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -128,7 +128,8 @@ extern int radeon_bo_init(struct radeon_device *rdev); extern void radeon_bo_fini(struct radeon_device *rdev); extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, struct list_head *head); -extern int radeon_bo_list_validate(struct list_head *head, int ring); +extern int radeon_bo_list_validate(struct ww_acquire_ctx *ticket, + struct list_head *head, int ring); extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, struct vm_area_struct *vma); extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index ce5a10c8d338..41efcec28cd8 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -550,6 +550,7 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev, struct radeon_fence **fence) { struct ttm_validate_buffer tv; + struct ww_acquire_ctx ticket; struct list_head head; struct radeon_ib ib; uint64_t addr; @@ -561,7 +562,7 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev, INIT_LIST_HEAD(&head); list_add(&tv.head, &head); - r = ttm_eu_reserve_buffers(&head); + r = ttm_eu_reserve_buffers(&ticket, &head); if (r) return r; @@ -569,16 +570,12 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev, radeon_uvd_force_into_uvd_segment(bo); r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); - if (r) { - ttm_eu_backoff_reservation(&head); - return r; - } + if (r) + goto err; r = radeon_ib_get(rdev, ring, &ib, NULL, 16); - if (r) { - ttm_eu_backoff_reservation(&head); - return r; - } + if (r) + goto err; addr = radeon_bo_gpu_offset(bo); ib.ptr[0] = PACKET0(UVD_GPCOM_VCPU_DATA0, 0); @@ -592,11 +589,9 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev, ib.length_dw = 16; r = radeon_ib_schedule(rdev, &ib, NULL); - if (r) { - ttm_eu_backoff_reservation(&head); - return r; - } - ttm_eu_fence_buffer_objects(&head, ib.fence); + if (r) + goto err; + ttm_eu_fence_buffer_objects(&ticket, &head, ib.fence); if (fence) *fence = radeon_fence_ref(ib.fence); @@ -604,6 +599,10 @@ static int radeon_uvd_send_msg(struct radeon_device *rdev, radeon_ib_free(rdev, &ib); radeon_bo_unref(&bo); return 0; + +err: + ttm_eu_backoff_reservation(&ticket, &head); + return r; } /* multiple fence commands without any stream commands in between can |