diff options
author | Monk Liu <Monk.Liu@amd.com> | 2017-09-15 01:40:31 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 15:14:13 -0400 |
commit | eb01abc7c4fd1faa26d0787f410894d9c704eb60 (patch) | |
tree | 645e1a8f4c2cae1784f9363e0c9bab99d9147c45 /drivers/gpu/drm/amd/amdgpu | |
parent | f840cc5f8447db7efff447a25bcddbf084bd3e2e (diff) |
drm/amdgpu:make ctx_add_fence interruptible(v2)
otherwise a gpu hang will make application couldn't be killed
under timedout=0 mode
v2:
Fix memoryleak job/job->s_fence issue
unlock mn
remove the ERROR msg after waiting being interrupted
Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 12 |
3 files changed, 23 insertions, 9 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 33e1d619d060..9cce59f6ada5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -735,8 +735,8 @@ struct amdgpu_ctx_mgr { | |||
735 | struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); | 735 | struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); |
736 | int amdgpu_ctx_put(struct amdgpu_ctx *ctx); | 736 | int amdgpu_ctx_put(struct amdgpu_ctx *ctx); |
737 | 737 | ||
738 | uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | 738 | int amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, |
739 | struct dma_fence *fence); | 739 | struct dma_fence *fence, uint64_t *seq); |
740 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, | 740 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, |
741 | struct amdgpu_ring *ring, uint64_t seq); | 741 | struct amdgpu_ring *ring, uint64_t seq); |
742 | 742 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 9f1202a4182f..c6a214f1e991 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -1129,6 +1129,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
1129 | struct amd_sched_entity *entity = &p->ctx->rings[ring->idx].entity; | 1129 | struct amd_sched_entity *entity = &p->ctx->rings[ring->idx].entity; |
1130 | struct amdgpu_job *job; | 1130 | struct amdgpu_job *job; |
1131 | unsigned i; | 1131 | unsigned i; |
1132 | uint64_t seq; | ||
1133 | |||
1132 | int r; | 1134 | int r; |
1133 | 1135 | ||
1134 | amdgpu_mn_lock(p->mn); | 1136 | amdgpu_mn_lock(p->mn); |
@@ -1158,10 +1160,20 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
1158 | job->fence_ctx = entity->fence_context; | 1160 | job->fence_ctx = entity->fence_context; |
1159 | p->fence = dma_fence_get(&job->base.s_fence->finished); | 1161 | p->fence = dma_fence_get(&job->base.s_fence->finished); |
1160 | 1162 | ||
1163 | r = amdgpu_ctx_add_fence(p->ctx, ring, p->fence, &seq); | ||
1164 | if (r) { | ||
1165 | dma_fence_put(p->fence); | ||
1166 | dma_fence_put(&job->base.s_fence->finished); | ||
1167 | amdgpu_job_free(job); | ||
1168 | amdgpu_mn_unlock(p->mn); | ||
1169 | return r; | ||
1170 | } | ||
1171 | |||
1161 | amdgpu_cs_post_dependencies(p); | 1172 | amdgpu_cs_post_dependencies(p); |
1162 | 1173 | ||
1163 | cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, p->fence); | 1174 | cs->out.handle = seq; |
1164 | job->uf_sequence = cs->out.handle; | 1175 | job->uf_sequence = seq; |
1176 | |||
1165 | amdgpu_job_free_resources(job); | 1177 | amdgpu_job_free_resources(job); |
1166 | 1178 | ||
1167 | trace_amdgpu_cs_ioctl(job); | 1179 | trace_amdgpu_cs_ioctl(job); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index a11e44340b23..75c933b1a432 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | |||
@@ -246,8 +246,8 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx) | |||
246 | return 0; | 246 | return 0; |
247 | } | 247 | } |
248 | 248 | ||
249 | uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | 249 | int amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, |
250 | struct dma_fence *fence) | 250 | struct dma_fence *fence, uint64_t* handler) |
251 | { | 251 | { |
252 | struct amdgpu_ctx_ring *cring = & ctx->rings[ring->idx]; | 252 | struct amdgpu_ctx_ring *cring = & ctx->rings[ring->idx]; |
253 | uint64_t seq = cring->sequence; | 253 | uint64_t seq = cring->sequence; |
@@ -258,9 +258,9 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | |||
258 | other = cring->fences[idx]; | 258 | other = cring->fences[idx]; |
259 | if (other) { | 259 | if (other) { |
260 | signed long r; | 260 | signed long r; |
261 | r = dma_fence_wait_timeout(other, false, MAX_SCHEDULE_TIMEOUT); | 261 | r = dma_fence_wait_timeout(other, true, MAX_SCHEDULE_TIMEOUT); |
262 | if (r < 0) | 262 | if (r < 0) |
263 | DRM_ERROR("Error (%ld) waiting for fence!\n", r); | 263 | return r; |
264 | } | 264 | } |
265 | 265 | ||
266 | dma_fence_get(fence); | 266 | dma_fence_get(fence); |
@@ -271,8 +271,10 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct amdgpu_ring *ring, | |||
271 | spin_unlock(&ctx->ring_lock); | 271 | spin_unlock(&ctx->ring_lock); |
272 | 272 | ||
273 | dma_fence_put(other); | 273 | dma_fence_put(other); |
274 | if (handler) | ||
275 | *handler = seq; | ||
274 | 276 | ||
275 | return seq; | 277 | return 0; |
276 | } | 278 | } |
277 | 279 | ||
278 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, | 280 | struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, |