diff options
| author | Christian König <christian.koenig@amd.com> | 2016-05-06 16:14:00 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2016-05-11 13:30:32 -0400 |
| commit | 758ac17f963f3497aae4e767d3a9eb68fea71f71 (patch) | |
| tree | e2007d7fa5077f91d7b6b5a05437fc0c1faef41d /drivers | |
| parent | d88bf583bd06eecb31f82871c90ef6a5a09b5766 (diff) | |
drm/amdgpu: fix and cleanup user fence handling v2
We leaked the BO in the error pass, additional to that we only have
one user fence for all IBs in a job.
v2: remove white space changes
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 19 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 55 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 2 |
4 files changed, 38 insertions, 47 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index d4c1eb7816f0..2a009c398dcb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -368,13 +368,6 @@ struct amdgpu_fence_driver { | |||
| 368 | #define AMDGPU_FENCE_FLAG_64BIT (1 << 0) | 368 | #define AMDGPU_FENCE_FLAG_64BIT (1 << 0) |
| 369 | #define AMDGPU_FENCE_FLAG_INT (1 << 1) | 369 | #define AMDGPU_FENCE_FLAG_INT (1 << 1) |
| 370 | 370 | ||
| 371 | struct amdgpu_user_fence { | ||
| 372 | /* write-back bo */ | ||
| 373 | struct amdgpu_bo *bo; | ||
| 374 | /* write-back address offset to bo start */ | ||
| 375 | uint32_t offset; | ||
| 376 | }; | ||
| 377 | |||
| 378 | int amdgpu_fence_driver_init(struct amdgpu_device *adev); | 371 | int amdgpu_fence_driver_init(struct amdgpu_device *adev); |
| 379 | void amdgpu_fence_driver_fini(struct amdgpu_device *adev); | 372 | void amdgpu_fence_driver_fini(struct amdgpu_device *adev); |
| 380 | void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev); | 373 | void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev); |
| @@ -741,10 +734,7 @@ struct amdgpu_ib { | |||
| 741 | uint32_t length_dw; | 734 | uint32_t length_dw; |
| 742 | uint64_t gpu_addr; | 735 | uint64_t gpu_addr; |
| 743 | uint32_t *ptr; | 736 | uint32_t *ptr; |
| 744 | struct amdgpu_user_fence *user; | ||
| 745 | uint32_t flags; | 737 | uint32_t flags; |
| 746 | /* resulting sequence number */ | ||
| 747 | uint64_t sequence; | ||
| 748 | }; | 738 | }; |
| 749 | 739 | ||
| 750 | enum amdgpu_ring_type { | 740 | enum amdgpu_ring_type { |
| @@ -1219,7 +1209,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring); | |||
| 1219 | struct amdgpu_cs_chunk { | 1209 | struct amdgpu_cs_chunk { |
| 1220 | uint32_t chunk_id; | 1210 | uint32_t chunk_id; |
| 1221 | uint32_t length_dw; | 1211 | uint32_t length_dw; |
| 1222 | uint32_t *kdata; | 1212 | void *kdata; |
| 1223 | }; | 1213 | }; |
| 1224 | 1214 | ||
| 1225 | struct amdgpu_cs_parser { | 1215 | struct amdgpu_cs_parser { |
| @@ -1263,7 +1253,12 @@ struct amdgpu_job { | |||
| 1263 | uint32_t gds_base, gds_size; | 1253 | uint32_t gds_base, gds_size; |
| 1264 | uint32_t gws_base, gws_size; | 1254 | uint32_t gws_base, gws_size; |
| 1265 | uint32_t oa_base, oa_size; | 1255 | uint32_t oa_base, oa_size; |
| 1266 | struct amdgpu_user_fence uf; | 1256 | |
| 1257 | /* user fence handling */ | ||
| 1258 | struct amdgpu_bo *uf_bo; | ||
| 1259 | uint32_t uf_offset; | ||
| 1260 | uint64_t uf_sequence; | ||
| 1261 | |||
| 1267 | }; | 1262 | }; |
| 1268 | #define to_amdgpu_job(sched_job) \ | 1263 | #define to_amdgpu_job(sched_job) \ |
| 1269 | container_of((sched_job), struct amdgpu_job, base) | 1264 | container_of((sched_job), struct amdgpu_job, base) |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 9ab2f0886a14..2bbeeb07c187 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
| @@ -87,33 +87,30 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, | 89 | static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, |
| 90 | struct amdgpu_user_fence *uf, | 90 | struct drm_amdgpu_cs_chunk_fence *data, |
| 91 | struct drm_amdgpu_cs_chunk_fence *fence_data) | 91 | uint32_t *offset) |
| 92 | { | 92 | { |
| 93 | struct drm_gem_object *gobj; | 93 | struct drm_gem_object *gobj; |
| 94 | uint32_t handle; | ||
| 95 | 94 | ||
| 96 | handle = fence_data->handle; | ||
| 97 | gobj = drm_gem_object_lookup(p->adev->ddev, p->filp, | 95 | gobj = drm_gem_object_lookup(p->adev->ddev, p->filp, |
| 98 | fence_data->handle); | 96 | data->handle); |
| 99 | if (gobj == NULL) | 97 | if (gobj == NULL) |
| 100 | return -EINVAL; | 98 | return -EINVAL; |
| 101 | 99 | ||
| 102 | uf->bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); | 100 | p->uf_entry.robj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); |
| 103 | uf->offset = fence_data->offset; | ||
| 104 | |||
| 105 | if (amdgpu_ttm_tt_get_usermm(uf->bo->tbo.ttm)) { | ||
| 106 | drm_gem_object_unreference_unlocked(gobj); | ||
| 107 | return -EINVAL; | ||
| 108 | } | ||
| 109 | |||
| 110 | p->uf_entry.robj = amdgpu_bo_ref(uf->bo); | ||
| 111 | p->uf_entry.priority = 0; | 101 | p->uf_entry.priority = 0; |
| 112 | p->uf_entry.tv.bo = &p->uf_entry.robj->tbo; | 102 | p->uf_entry.tv.bo = &p->uf_entry.robj->tbo; |
| 113 | p->uf_entry.tv.shared = true; | 103 | p->uf_entry.tv.shared = true; |
| 114 | p->uf_entry.user_pages = NULL; | 104 | p->uf_entry.user_pages = NULL; |
| 105 | *offset = data->offset; | ||
| 115 | 106 | ||
| 116 | drm_gem_object_unreference_unlocked(gobj); | 107 | drm_gem_object_unreference_unlocked(gobj); |
| 108 | |||
| 109 | if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) { | ||
| 110 | amdgpu_bo_unref(&p->uf_entry.robj); | ||
| 111 | return -EINVAL; | ||
| 112 | } | ||
| 113 | |||
| 117 | return 0; | 114 | return 0; |
| 118 | } | 115 | } |
| 119 | 116 | ||
| @@ -124,8 +121,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
| 124 | union drm_amdgpu_cs *cs = data; | 121 | union drm_amdgpu_cs *cs = data; |
| 125 | uint64_t *chunk_array_user; | 122 | uint64_t *chunk_array_user; |
| 126 | uint64_t *chunk_array; | 123 | uint64_t *chunk_array; |
| 127 | struct amdgpu_user_fence uf = {}; | ||
| 128 | unsigned size, num_ibs = 0; | 124 | unsigned size, num_ibs = 0; |
| 125 | uint32_t uf_offset = 0; | ||
| 129 | int i; | 126 | int i; |
| 130 | int ret; | 127 | int ret; |
| 131 | 128 | ||
| @@ -200,7 +197,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
| 200 | goto free_partial_kdata; | 197 | goto free_partial_kdata; |
| 201 | } | 198 | } |
| 202 | 199 | ||
| 203 | ret = amdgpu_cs_user_fence_chunk(p, &uf, (void *)p->chunks[i].kdata); | 200 | ret = amdgpu_cs_user_fence_chunk(p, p->chunks[i].kdata, |
| 201 | &uf_offset); | ||
| 204 | if (ret) | 202 | if (ret) |
| 205 | goto free_partial_kdata; | 203 | goto free_partial_kdata; |
| 206 | 204 | ||
| @@ -219,7 +217,10 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
| 219 | if (ret) | 217 | if (ret) |
| 220 | goto free_all_kdata; | 218 | goto free_all_kdata; |
| 221 | 219 | ||
| 222 | p->job->uf = uf; | 220 | if (p->uf_entry.robj) { |
| 221 | p->job->uf_bo = amdgpu_bo_ref(p->uf_entry.robj); | ||
| 222 | p->job->uf_offset = uf_offset; | ||
| 223 | } | ||
| 223 | 224 | ||
| 224 | kfree(chunk_array); | 225 | kfree(chunk_array); |
| 225 | return 0; | 226 | return 0; |
| @@ -377,7 +378,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
| 377 | INIT_LIST_HEAD(&duplicates); | 378 | INIT_LIST_HEAD(&duplicates); |
| 378 | amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); | 379 | amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); |
| 379 | 380 | ||
| 380 | if (p->job->uf.bo) | 381 | if (p->uf_entry.robj) |
| 381 | list_add(&p->uf_entry.tv.head, &p->validated); | 382 | list_add(&p->uf_entry.tv.head, &p->validated); |
| 382 | 383 | ||
| 383 | if (need_mmap_lock) | 384 | if (need_mmap_lock) |
| @@ -760,17 +761,11 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, | |||
| 760 | j++; | 761 | j++; |
| 761 | } | 762 | } |
| 762 | 763 | ||
| 763 | /* wrap the last IB with user fence */ | 764 | /* UVD & VCE fw doesn't support user fences */ |
| 764 | if (parser->job->uf.bo) { | 765 | if (parser->job->uf_bo && ( |
| 765 | struct amdgpu_ib *ib = &parser->job->ibs[parser->job->num_ibs - 1]; | 766 | parser->job->ring->type == AMDGPU_RING_TYPE_UVD || |
| 766 | 767 | parser->job->ring->type == AMDGPU_RING_TYPE_VCE)) | |
| 767 | /* UVD & VCE fw doesn't support user fences */ | 768 | return -EINVAL; |
| 768 | if (parser->job->ring->type == AMDGPU_RING_TYPE_UVD || | ||
| 769 | parser->job->ring->type == AMDGPU_RING_TYPE_VCE) | ||
| 770 | return -EINVAL; | ||
| 771 | |||
| 772 | ib->user = &parser->job->uf; | ||
| 773 | } | ||
| 774 | 769 | ||
| 775 | return 0; | 770 | return 0; |
| 776 | } | 771 | } |
| @@ -856,7 +851,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
| 856 | job->ctx = entity->fence_context; | 851 | job->ctx = entity->fence_context; |
| 857 | p->fence = fence_get(fence); | 852 | p->fence = fence_get(fence); |
| 858 | cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, fence); | 853 | cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, fence); |
| 859 | job->ibs[job->num_ibs - 1].sequence = cs->out.handle; | 854 | job->uf_sequence = cs->out.handle; |
| 860 | 855 | ||
| 861 | trace_amdgpu_cs_ioctl(job); | 856 | trace_amdgpu_cs_ioctl(job); |
| 862 | amd_sched_entity_push_job(&job->base); | 857 | amd_sched_entity_push_job(&job->base); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 201aceb01d8a..34e35423b78e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
| @@ -203,10 +203,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, | |||
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | /* wrap the last IB with fence */ | 205 | /* wrap the last IB with fence */ |
| 206 | if (ib->user) { | 206 | if (job && job->uf_bo) { |
| 207 | uint64_t addr = amdgpu_bo_gpu_offset(ib->user->bo); | 207 | uint64_t addr = amdgpu_bo_gpu_offset(job->uf_bo); |
| 208 | addr += ib->user->offset; | 208 | |
| 209 | amdgpu_ring_emit_fence(ring, addr, ib->sequence, | 209 | addr += job->uf_offset; |
| 210 | amdgpu_ring_emit_fence(ring, addr, job->uf_sequence, | ||
| 210 | AMDGPU_FENCE_FLAG_64BIT); | 211 | AMDGPU_FENCE_FLAG_64BIT); |
| 211 | } | 212 | } |
| 212 | 213 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 8ea68d0cfad6..f0dafa514fe4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |||
| @@ -97,7 +97,7 @@ void amdgpu_job_free(struct amdgpu_job *job) | |||
| 97 | amdgpu_sa_bo_free(job->adev, &job->ibs[i].sa_bo, f); | 97 | amdgpu_sa_bo_free(job->adev, &job->ibs[i].sa_bo, f); |
| 98 | fence_put(job->fence); | 98 | fence_put(job->fence); |
| 99 | 99 | ||
| 100 | amdgpu_bo_unref(&job->uf.bo); | 100 | amdgpu_bo_unref(&job->uf_bo); |
| 101 | amdgpu_sync_free(&job->sync); | 101 | amdgpu_sync_free(&job->sync); |
| 102 | 102 | ||
| 103 | if (!job->base.use_sched) | 103 | if (!job->base.use_sched) |
