[PATCH 2/2] drm/amd/sched: add schuduling policy

Chunming Zhou David1.Zhou at amd.com
Thu Mar 16 09:00:49 UTC 2017


if high priority rq is full, then process with low priority could be starve.
Add policy for this problem, the high proiority can ahead of next priority queue,
the ratio is 2 : 1.

Change-Id: I58f4a6b9cdce8689b18dd8e83dd6e2cf5f99d5fb
Signed-off-by: Chunming Zhou <David1.Zhou at amd.com>
---
 drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 26 +++++++++++++++++++++++---
 drivers/gpu/drm/amd/scheduler/gpu_scheduler.h |  2 ++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
index 0f439dd..4637b6f 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
@@ -35,11 +35,16 @@
 static void amd_sched_process_job(struct fence *f, struct fence_cb *cb);
 
 /* Initialize a given run queue struct */
-static void amd_sched_rq_init(struct amd_sched_rq *rq)
+static void amd_sched_rq_init(struct amd_gpu_scheduler *sched, enum
+			      amd_sched_priority pri)
 {
+	struct amd_sched_rq *rq = &sched->sched_rq[pri];
+
 	spin_lock_init(&rq->lock);
 	INIT_LIST_HEAD(&rq->entities);
 	rq->current_entity = NULL;
+	rq->wait_base = pri * 2;
+	rq->wait = rq->wait_base;
 }
 
 static void amd_sched_rq_add_entity(struct amd_sched_rq *rq,
@@ -494,17 +499,32 @@ static void amd_sched_wakeup(struct amd_gpu_scheduler *sched)
 {
 	struct amd_sched_entity *entity;
 	int i;
+	bool skip;
 
 	if (!amd_sched_ready(sched))
 		return NULL;
 
+retry:
+	skip = false;
 	/* Kernel run queue has higher priority than normal run queue*/
 	for (i = AMD_SCHED_PRIORITY_MAX - 1; i >= AMD_SCHED_PRIORITY_MIN; i--) {
+		if ((i > AMD_SCHED_PRIORITY_MIN) &&
+		    (sched->sched_rq[i - 1].wait >= sched->sched_rq[i].wait_base)) {
+			sched->sched_rq[i - 1].wait = sched->sched_rq[i - 1].wait_base;
+			skip = true;
+			continue;
+		}
 		entity = amd_sched_rq_select_entity(&sched->sched_rq[i]);
-		if (entity)
+		if (entity) {
+			if (i > AMD_SCHED_PRIORITY_MIN)
+				sched->sched_rq[i - 1].wait++;
 			break;
+		}
 	}
 
+	if (!entity && skip)
+		goto retry;
+
 	return entity;
 }
 
@@ -608,7 +628,7 @@ int amd_sched_init(struct amd_gpu_scheduler *sched,
 	sched->name = name;
 	sched->timeout = timeout;
 	for (i = AMD_SCHED_PRIORITY_MIN; i < AMD_SCHED_PRIORITY_MAX; i++)
-		amd_sched_rq_init(&sched->sched_rq[i]);
+		amd_sched_rq_init(sched, i);
 
 	init_waitqueue_head(&sched->wake_up_worker);
 	init_waitqueue_head(&sched->job_scheduled);
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
index 99f0240..4caed30 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
@@ -64,6 +64,8 @@ struct amd_sched_rq {
 	spinlock_t		lock;
 	struct list_head	entities;
 	struct amd_sched_entity	*current_entity;
+	int wait_base;
+	int wait;
 };
 
 struct amd_sched_fence {
-- 
1.9.1



More information about the amd-gfx mailing list