diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0710-drm-sched-Add-boolean-to-mark-if-sched-is-ready-to-w.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/0710-drm-sched-Add-boolean-to-mark-if-sched-is-ready-to-w.patch | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0710-drm-sched-Add-boolean-to-mark-if-sched-is-ready-to-w.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0710-drm-sched-Add-boolean-to-mark-if-sched-is-ready-to-w.patch new file mode 100644 index 00000000..45552cc7 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0710-drm-sched-Add-boolean-to-mark-if-sched-is-ready-to-w.patch @@ -0,0 +1,118 @@ +From 5a9a2ff2a6c04d48ecb949526c797d73f6d37fc7 Mon Sep 17 00:00:00 2001 +From: Andrey Grodzovsky <andrey.grodzovsky@amd.com> +Date: Thu, 18 Oct 2018 12:32:46 -0400 +Subject: [PATCH 0710/2940] drm/sched: Add boolean to mark if sched is ready to + work v5 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Problem: +A particular scheduler may become unsuable (underlying HW) after +some event (e.g. GPU reset). If it's later chosen by +the get free sched. policy a command will fail to be +submitted. + +Fix: +Add a driver specific callback to report the sched status so +rq with bad sched can be avoided in favor of working one or +none in which case job init will fail. + +v2: Switch from driver callback to flag in scheduler. + +v3: rebase + +v4: Remove ready paramter from drm_sched_init, set +uncoditionally to true once init done. + +v5: fix missed change in v3d in v4 (Alex) + +Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com> +Reviewed-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/scheduler/sched_entity.c | 9 ++++++++- + drivers/gpu/drm/scheduler/sched_main.c | 6 ++++++ + include/drm/gpu_scheduler.h | 3 +++ + 3 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c +index 4e5e95c0cab5..87738f91eee6 100644 +--- a/drivers/gpu/drm/scheduler/sched_entity.c ++++ b/drivers/gpu/drm/scheduler/sched_entity.c +@@ -130,7 +130,14 @@ drm_sched_entity_get_free_sched(struct drm_sched_entity *entity) + int i; + + for (i = 0; i < entity->num_rq_list; ++i) { +- num_jobs = atomic_read(&entity->rq_list[i]->sched->num_jobs); ++ struct drm_gpu_scheduler *sched = entity->rq_list[i]->sched; ++ ++ if (!entity->rq_list[i]->sched->ready) { ++ DRM_WARN("sched%s is not ready, skipping", sched->name); ++ continue; ++ } ++ ++ num_jobs = atomic_read(&sched->num_jobs); + if (num_jobs < min_jobs) { + min_jobs = num_jobs; + rq = entity->rq_list[i]; +diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c +index 9ca741f3a0bc..b7e4572f811f 100644 +--- a/drivers/gpu/drm/scheduler/sched_main.c ++++ b/drivers/gpu/drm/scheduler/sched_main.c +@@ -372,6 +372,9 @@ int drm_sched_job_init(struct drm_sched_job *job, + struct drm_gpu_scheduler *sched; + + drm_sched_entity_select_rq(entity); ++ if (!entity->rq) ++ return -ENOENT; ++ + sched = entity->rq->sched; + + job->sched = sched; +@@ -585,6 +588,7 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, + return PTR_ERR(sched->thread); + } + ++ sched->ready = true; + return 0; + } + EXPORT_SYMBOL(drm_sched_init); +@@ -600,5 +604,7 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched) + { + if (sched->thread) + kthread_stop(sched->thread); ++ ++ sched->ready = false; + } + EXPORT_SYMBOL(drm_sched_fini); +diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h +index bc6a2a1f00fc..63f74e95caff 100644 +--- a/include/drm/gpu_scheduler.h ++++ b/include/drm/gpu_scheduler.h +@@ -262,6 +262,7 @@ struct drm_sched_backend_ops { + * @hang_limit: once the hangs by a job crosses this limit then it is marked + * 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 + * + * One scheduler is implemented for each hardware ring. + */ +@@ -280,12 +281,14 @@ struct drm_gpu_scheduler { + spinlock_t job_list_lock; + int hang_limit; + atomic_t num_jobs; ++ bool ready; + }; + + int drm_sched_init(struct drm_gpu_scheduler *sched, + const struct drm_sched_backend_ops *ops, + uint32_t hw_submission, unsigned hang_limit, long timeout, + const char *name); ++ + void drm_sched_fini(struct drm_gpu_scheduler *sched); + int drm_sched_job_init(struct drm_sched_job *job, + struct drm_sched_entity *entity, +-- +2.17.1 + |