summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>2019-04-18 11:00:23 -0400
committerAlex Deucher <alexander.deucher@amd.com>2019-05-02 15:50:55 -0500
commita5343b8a2ca5799ee6370e3cca77369a4c598221 (patch)
treecca91effac12b23864f57cc409e29d7e27dbdce9
parent290764af7e369f0001175dc8c3cb747aa9903bb8 (diff)
downloadlinux-a5343b8a2ca5799ee6370e3cca77369a4c598221.tar.bz2
drm/scheduler: Add flag to hint the release of guilty job.
Problem: Sched thread's cleanup function races against TO handler and removes the guilty job from mirror list and we have no way of differentiating if the job was removed from within the TO handler or from the sched thread's clean-up function. Fix: Add a flag to scheduler to hint the TO handler that the guilty job needs to be explicitly released. v2: whitespace fix Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/1555599624-12285-5-git-send-email-andrey.grodzovsky@amd.com
-rw-r--r--drivers/gpu/drm/scheduler/sched_main.c9
-rw-r--r--include/drm/gpu_scheduler.h2
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 03e6bd8a1a42..f8f0e1c19002 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -293,8 +293,10 @@ static void drm_sched_job_timedout(struct work_struct *work)
* Guilty job did complete and hence needs to be manually removed
* See drm_sched_stop doc.
*/
- if (list_empty(&job->node))
+ if (sched->free_guilty) {
job->sched->ops->free_job(job);
+ sched->free_guilty = false;
+ }
spin_lock_irqsave(&sched->job_list_lock, flags);
drm_sched_start_timeout(sched);
@@ -395,10 +397,13 @@ void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad)
/*
* We must keep bad job alive for later use during
- * recovery by some of the drivers
+ * recovery by some of the drivers but leave a hint
+ * that the guilty job must be released.
*/
if (bad != s_job)
sched->ops->free_job(s_job);
+ else
+ sched->free_guilty = true;
}
}
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 9ee0f2735d71..57b4121c750a 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -259,6 +259,7 @@ struct drm_sched_backend_ops {
* guilty and it will be considered for scheduling further.
* @num_jobs: the number of jobs in queue in the scheduler
* @ready: marks if the underlying HW is ready to work
+ * @free_guilty: A hit to time out handler to free the guilty job.
*
* One scheduler is implemented for each hardware ring.
*/
@@ -279,6 +280,7 @@ struct drm_gpu_scheduler {
int hang_limit;
atomic_t num_jobs;
bool ready;
+ bool free_guilty;
};
int drm_sched_init(struct drm_gpu_scheduler *sched,