diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/sched_fence.c | 1 |
6 files changed, 62 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9bf72b24495c..ccb28468ece8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -754,6 +754,7 @@ void amdgpu_job_free(struct amdgpu_job *job); | |||
754 | int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, | 754 | int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, |
755 | struct amd_sched_entity *entity, void *owner, | 755 | struct amd_sched_entity *entity, void *owner, |
756 | struct fence **f); | 756 | struct fence **f); |
757 | void amdgpu_job_timeout_func(struct work_struct *work); | ||
757 | 758 | ||
758 | struct amdgpu_ring { | 759 | struct amdgpu_ring { |
759 | struct amdgpu_device *adev; | 760 | struct amdgpu_device *adev; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 23266b454aec..9025671d21c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -871,6 +871,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | |||
871 | 871 | ||
872 | r = amd_sched_job_init(&job->base, &ring->sched, | 872 | r = amd_sched_job_init(&job->base, &ring->sched, |
873 | &p->ctx->rings[ring->idx].entity, | 873 | &p->ctx->rings[ring->idx].entity, |
874 | amdgpu_job_timeout_func, | ||
874 | p->filp, &fence); | 875 | p->filp, &fence); |
875 | if (r) { | 876 | if (r) { |
876 | amdgpu_job_free(job); | 877 | amdgpu_job_free(job); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 23468088a995..961cae4a1955 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |||
@@ -34,6 +34,15 @@ static void amdgpu_job_free_handler(struct work_struct *ws) | |||
34 | kfree(job); | 34 | kfree(job); |
35 | } | 35 | } |
36 | 36 | ||
37 | void amdgpu_job_timeout_func(struct work_struct *work) | ||
38 | { | ||
39 | struct amdgpu_job *job = container_of(work, struct amdgpu_job, base.work_tdr.work); | ||
40 | DRM_ERROR("ring %s timeout, last signaled seq=%u, last emitted seq=%u\n", | ||
41 | job->base.sched->name, | ||
42 | (uint32_t)atomic_read(&job->ring->fence_drv.last_seq), | ||
43 | job->ring->fence_drv.sync_seq); | ||
44 | } | ||
45 | |||
37 | int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, | 46 | int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, |
38 | struct amdgpu_job **job) | 47 | struct amdgpu_job **job) |
39 | { | 48 | { |
@@ -103,7 +112,10 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, | |||
103 | if (!f) | 112 | if (!f) |
104 | return -EINVAL; | 113 | return -EINVAL; |
105 | 114 | ||
106 | r = amd_sched_job_init(&job->base, &ring->sched, entity, owner, &fence); | 115 | r = amd_sched_job_init(&job->base, &ring->sched, |
116 | entity, owner, | ||
117 | amdgpu_job_timeout_func, | ||
118 | &fence); | ||
107 | if (r) | 119 | if (r) |
108 | return r; | 120 | return r; |
109 | 121 | ||
@@ -180,4 +192,6 @@ err: | |||
180 | struct amd_sched_backend_ops amdgpu_sched_ops = { | 192 | struct amd_sched_backend_ops amdgpu_sched_ops = { |
181 | .dependency = amdgpu_job_dependency, | 193 | .dependency = amdgpu_job_dependency, |
182 | .run_job = amdgpu_job_run, | 194 | .run_job = amdgpu_job_run, |
195 | .begin_job = amd_sched_job_begin, | ||
196 | .finish_job = amd_sched_job_finish, | ||
183 | }; | 197 | }; |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 9a9fffdc272b..b7e8071448c6 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
@@ -324,6 +324,40 @@ static void amd_sched_free_job(struct fence *f, struct fence_cb *cb) { | |||
324 | schedule_work(&job->work_free_job); | 324 | schedule_work(&job->work_free_job); |
325 | } | 325 | } |
326 | 326 | ||
327 | /* job_finish is called after hw fence signaled, and | ||
328 | * the job had already been deleted from ring_mirror_list | ||
329 | */ | ||
330 | void amd_sched_job_finish(struct amd_sched_job *s_job) | ||
331 | { | ||
332 | struct amd_sched_job *next; | ||
333 | struct amd_gpu_scheduler *sched = s_job->sched; | ||
334 | |||
335 | if (sched->timeout != MAX_SCHEDULE_TIMEOUT) { | ||
336 | cancel_delayed_work(&s_job->work_tdr); /*TODO: how to deal the case that tdr is running */ | ||
337 | |||
338 | /* queue TDR for next job */ | ||
339 | next = list_first_entry_or_null(&sched->ring_mirror_list, | ||
340 | struct amd_sched_job, node); | ||
341 | |||
342 | if (next) { | ||
343 | INIT_DELAYED_WORK(&next->work_tdr, s_job->timeout_callback); | ||
344 | schedule_delayed_work(&next->work_tdr, sched->timeout); | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | |||
349 | void amd_sched_job_begin(struct amd_sched_job *s_job) | ||
350 | { | ||
351 | struct amd_gpu_scheduler *sched = s_job->sched; | ||
352 | |||
353 | if (sched->timeout != MAX_SCHEDULE_TIMEOUT && | ||
354 | list_first_entry_or_null(&sched->ring_mirror_list, struct amd_sched_job, node) == s_job) | ||
355 | { | ||
356 | INIT_DELAYED_WORK(&s_job->work_tdr, s_job->timeout_callback); | ||
357 | schedule_delayed_work(&s_job->work_tdr, sched->timeout); | ||
358 | } | ||
359 | } | ||
360 | |||
327 | /** | 361 | /** |
328 | * Submit a job to the job queue | 362 | * Submit a job to the job queue |
329 | * | 363 | * |
@@ -347,6 +381,7 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job) | |||
347 | int amd_sched_job_init(struct amd_sched_job *job, | 381 | int amd_sched_job_init(struct amd_sched_job *job, |
348 | struct amd_gpu_scheduler *sched, | 382 | struct amd_gpu_scheduler *sched, |
349 | struct amd_sched_entity *entity, | 383 | struct amd_sched_entity *entity, |
384 | void (*timeout_cb)(struct work_struct *work), | ||
350 | void *owner, struct fence **fence) | 385 | void *owner, struct fence **fence) |
351 | { | 386 | { |
352 | INIT_LIST_HEAD(&job->node); | 387 | INIT_LIST_HEAD(&job->node); |
@@ -357,6 +392,7 @@ int amd_sched_job_init(struct amd_sched_job *job, | |||
357 | return -ENOMEM; | 392 | return -ENOMEM; |
358 | 393 | ||
359 | job->s_fence->s_job = job; | 394 | job->s_fence->s_job = job; |
395 | job->timeout_callback = timeout_cb; | ||
360 | 396 | ||
361 | if (fence) | 397 | if (fence) |
362 | *fence = &job->s_fence->base; | 398 | *fence = &job->s_fence->base; |
@@ -415,6 +451,7 @@ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb) | |||
415 | /* remove job from ring_mirror_list */ | 451 | /* remove job from ring_mirror_list */ |
416 | spin_lock_irqsave(&sched->job_list_lock, flags); | 452 | spin_lock_irqsave(&sched->job_list_lock, flags); |
417 | list_del_init(&s_fence->s_job->node); | 453 | list_del_init(&s_fence->s_job->node); |
454 | sched->ops->finish_job(s_fence->s_job); | ||
418 | spin_unlock_irqrestore(&sched->job_list_lock, flags); | 455 | spin_unlock_irqrestore(&sched->job_list_lock, flags); |
419 | 456 | ||
420 | amd_sched_fence_signal(s_fence); | 457 | amd_sched_fence_signal(s_fence); |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index b26148d24a3d..a5700aded5bf 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | |||
@@ -85,6 +85,8 @@ struct amd_sched_job { | |||
85 | struct fence_cb cb_free_job; | 85 | struct fence_cb cb_free_job; |
86 | struct work_struct work_free_job; | 86 | struct work_struct work_free_job; |
87 | struct list_head node; | 87 | struct list_head node; |
88 | struct delayed_work work_tdr; | ||
89 | void (*timeout_callback) (struct work_struct *work); | ||
88 | }; | 90 | }; |
89 | 91 | ||
90 | extern const struct fence_ops amd_sched_fence_ops; | 92 | extern const struct fence_ops amd_sched_fence_ops; |
@@ -105,6 +107,8 @@ static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f) | |||
105 | struct amd_sched_backend_ops { | 107 | struct amd_sched_backend_ops { |
106 | struct fence *(*dependency)(struct amd_sched_job *sched_job); | 108 | struct fence *(*dependency)(struct amd_sched_job *sched_job); |
107 | struct fence *(*run_job)(struct amd_sched_job *sched_job); | 109 | struct fence *(*run_job)(struct amd_sched_job *sched_job); |
110 | void (*begin_job)(struct amd_sched_job *sched_job); | ||
111 | void (*finish_job)(struct amd_sched_job *sched_job); | ||
108 | }; | 112 | }; |
109 | 113 | ||
110 | enum amd_sched_priority { | 114 | enum amd_sched_priority { |
@@ -150,7 +154,10 @@ void amd_sched_fence_signal(struct amd_sched_fence *fence); | |||
150 | int amd_sched_job_init(struct amd_sched_job *job, | 154 | int amd_sched_job_init(struct amd_sched_job *job, |
151 | struct amd_gpu_scheduler *sched, | 155 | struct amd_gpu_scheduler *sched, |
152 | struct amd_sched_entity *entity, | 156 | struct amd_sched_entity *entity, |
157 | void (*timeout_cb)(struct work_struct *work), | ||
153 | void *owner, struct fence **fence); | 158 | void *owner, struct fence **fence); |
154 | void amd_sched_job_pre_schedule(struct amd_gpu_scheduler *sched , | 159 | void amd_sched_job_pre_schedule(struct amd_gpu_scheduler *sched , |
155 | struct amd_sched_job *s_job); | 160 | struct amd_sched_job *s_job); |
161 | void amd_sched_job_finish(struct amd_sched_job *s_job); | ||
162 | void amd_sched_job_begin(struct amd_sched_job *s_job); | ||
156 | #endif | 163 | #endif |
diff --git a/drivers/gpu/drm/amd/scheduler/sched_fence.c b/drivers/gpu/drm/amd/scheduler/sched_fence.c index 33ddd38185d5..2a732c490375 100644 --- a/drivers/gpu/drm/amd/scheduler/sched_fence.c +++ b/drivers/gpu/drm/amd/scheduler/sched_fence.c | |||
@@ -63,6 +63,7 @@ void amd_sched_job_pre_schedule(struct amd_gpu_scheduler *sched , | |||
63 | unsigned long flags; | 63 | unsigned long flags; |
64 | spin_lock_irqsave(&sched->job_list_lock, flags); | 64 | spin_lock_irqsave(&sched->job_list_lock, flags); |
65 | list_add_tail(&s_job->node, &sched->ring_mirror_list); | 65 | list_add_tail(&s_job->node, &sched->ring_mirror_list); |
66 | sched->ops->begin_job(s_job); | ||
66 | spin_unlock_irqrestore(&sched->job_list_lock, flags); | 67 | spin_unlock_irqrestore(&sched->job_list_lock, flags); |
67 | } | 68 | } |
68 | 69 | ||