drm/amdgpu: rework TDR in scheduler (v2)

Add two callbacks to scheduler to maintain jobs, and invoked for
job timeout calculations. Now TDR measures time gap from
job is processed by hw.

v2:
fix typo

Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Monk Liu
2016-03-04 18:51:02 +08:00
کامیت شده توسط Alex Deucher
والد cccd9bce97
کامیت 0de2479c95
6فایلهای تغییر یافته به همراه62 افزوده شده و 1 حذف شده

مشاهده پرونده

@@ -324,6 +324,40 @@ static void amd_sched_free_job(struct fence *f, struct fence_cb *cb) {
schedule_work(&job->work_free_job);
}
/* job_finish is called after hw fence signaled, and
* the job had already been deleted from ring_mirror_list
*/
void amd_sched_job_finish(struct amd_sched_job *s_job)
{
struct amd_sched_job *next;
struct amd_gpu_scheduler *sched = s_job->sched;
if (sched->timeout != MAX_SCHEDULE_TIMEOUT) {
cancel_delayed_work(&s_job->work_tdr); /*TODO: how to deal the case that tdr is running */
/* queue TDR for next job */
next = list_first_entry_or_null(&sched->ring_mirror_list,
struct amd_sched_job, node);
if (next) {
INIT_DELAYED_WORK(&next->work_tdr, s_job->timeout_callback);
schedule_delayed_work(&next->work_tdr, sched->timeout);
}
}
}
void amd_sched_job_begin(struct amd_sched_job *s_job)
{
struct amd_gpu_scheduler *sched = s_job->sched;
if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
list_first_entry_or_null(&sched->ring_mirror_list, struct amd_sched_job, node) == s_job)
{
INIT_DELAYED_WORK(&s_job->work_tdr, s_job->timeout_callback);
schedule_delayed_work(&s_job->work_tdr, sched->timeout);
}
}
/**
* Submit a job to the job queue
*
@@ -347,6 +381,7 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job)
int amd_sched_job_init(struct amd_sched_job *job,
struct amd_gpu_scheduler *sched,
struct amd_sched_entity *entity,
void (*timeout_cb)(struct work_struct *work),
void *owner, struct fence **fence)
{
INIT_LIST_HEAD(&job->node);
@@ -357,6 +392,7 @@ int amd_sched_job_init(struct amd_sched_job *job,
return -ENOMEM;
job->s_fence->s_job = job;
job->timeout_callback = timeout_cb;
if (fence)
*fence = &job->s_fence->base;
@@ -415,6 +451,7 @@ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb)
/* remove job from ring_mirror_list */
spin_lock_irqsave(&sched->job_list_lock, flags);
list_del_init(&s_fence->s_job->node);
sched->ops->finish_job(s_fence->s_job);
spin_unlock_irqrestore(&sched->job_list_lock, flags);
amd_sched_fence_signal(s_fence);

مشاهده پرونده

@@ -85,6 +85,8 @@ struct amd_sched_job {
struct fence_cb cb_free_job;
struct work_struct work_free_job;
struct list_head node;
struct delayed_work work_tdr;
void (*timeout_callback) (struct work_struct *work);
};
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)
struct amd_sched_backend_ops {
struct fence *(*dependency)(struct amd_sched_job *sched_job);
struct fence *(*run_job)(struct amd_sched_job *sched_job);
void (*begin_job)(struct amd_sched_job *sched_job);
void (*finish_job)(struct amd_sched_job *sched_job);
};
enum amd_sched_priority {
@@ -150,7 +154,10 @@ void amd_sched_fence_signal(struct amd_sched_fence *fence);
int amd_sched_job_init(struct amd_sched_job *job,
struct amd_gpu_scheduler *sched,
struct amd_sched_entity *entity,
void (*timeout_cb)(struct work_struct *work),
void *owner, struct fence **fence);
void amd_sched_job_pre_schedule(struct amd_gpu_scheduler *sched ,
struct amd_sched_job *s_job);
void amd_sched_job_finish(struct amd_sched_job *s_job);
void amd_sched_job_begin(struct amd_sched_job *s_job);
#endif

مشاهده پرونده

@@ -63,6 +63,7 @@ void amd_sched_job_pre_schedule(struct amd_gpu_scheduler *sched ,
unsigned long flags;
spin_lock_irqsave(&sched->job_list_lock, flags);
list_add_tail(&s_job->node, &sched->ring_mirror_list);
sched->ops->begin_job(s_job);
spin_unlock_irqrestore(&sched->job_list_lock, flags);
}