[PATCH 2/2] drm/scheduler: add last_scheduled dependency handling

Christian König ckoenig.leichtzumerken at gmail.com
Mon Aug 6 12:19:16 UTC 2018


This fixes accessing the last_scheduled fence from multiple threads as
well as makes it easier to move entities between schedulers.

Signed-off-by: Christian König <christian.koenig at amd.com>
---
 drivers/gpu/drm/scheduler/gpu_scheduler.c | 34 +++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index 029863726c99..e4b71a543481 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -523,6 +523,29 @@ static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity)
 	return false;
 }
 
+static bool drm_sched_entity_last_scheduled_dep(struct drm_sched_entity *entity)
+{
+	struct drm_sched_fence *s_fence;
+
+	if (!entity->last_scheduled)
+		return false;
+
+	/*
+	 * Check if the last submission was handled by a different scheduler
+	 */
+	s_fence = to_drm_sched_fence(entity->last_scheduled);
+	if (s_fence && s_fence->sched != entity->rq->sched) {
+		entity->dependency = dma_fence_get(entity->last_scheduled);
+		if (!dma_fence_add_callback(entity->dependency, &entity->cb,
+					    drm_sched_entity_wakeup))
+			return true;
+
+		dma_fence_put(entity->dependency);
+		entity->dependency = NULL;
+	}
+	return false;
+}
+
 static struct drm_sched_job *
 drm_sched_entity_pop_job(struct drm_sched_entity *entity)
 {
@@ -537,6 +560,9 @@ drm_sched_entity_pop_job(struct drm_sched_entity *entity)
 		if (drm_sched_entity_add_dependency_cb(entity))
 			return NULL;
 
+	if (drm_sched_entity_last_scheduled_dep(entity))
+		return NULL;
+
 	/* skip jobs from entity that marked guilty */
 	if (entity->guilty && atomic_read(entity->guilty))
 		dma_fence_set_error(&sched_job->s_fence->finished, -ECANCELED);
@@ -564,14 +590,10 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job,
 			       struct drm_sched_entity *entity)
 {
 	struct drm_sched_rq *rq = entity->rq;
-	bool first, reschedule, idle;
+	bool first;
 
-	idle = entity->last_scheduled == NULL ||
-		dma_fence_is_signaled(entity->last_scheduled);
 	first = spsc_queue_count(&entity->job_queue) == 0;
-	reschedule = idle && first && (entity->num_rq_list > 1);
-
-	if (reschedule) {
+	if (first && (entity->num_rq_list > 1)) {
 		rq = drm_sched_entity_get_free_sched(entity);
 		spin_lock(&entity->rq_lock);
 		drm_sched_rq_remove_entity(entity->rq, entity);
-- 
2.14.1



More information about the dri-devel mailing list