+
+ return ts;
+}
+
struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity
*entity)
{
- struct drm_sched_job *sched_job;
+ struct drm_sched_job *sched_job, *next_job;
sched_job = drm_sched_entity_queue_peek(entity);
if (!sched_job)
@@ -491,21 +506,21 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct
drm_sched_entity *entity)
* Update the entity's location in the min heap according to
* the timestamp of the next job, if any.
*/
- if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) {
- struct drm_sched_job *next;
+ next_job = drm_sched_entity_queue_peek(entity);
+ if (next_job) {
+ struct drm_sched_rq *rq;
+ ktime_t ts;
- next = drm_sched_entity_queue_peek(entity);
- if (next) {
- struct drm_sched_rq *rq;
-
- spin_lock(&entity->lock);
- rq = entity->rq;
- spin_lock(&rq->lock);
- drm_sched_rq_update_fifo_locked(entity, rq,
- next->submit_ts);
- spin_unlock(&rq->lock);
- spin_unlock(&entity->lock);
- }
+ spin_lock(&entity->lock);
+ rq = entity->rq;
+ spin_lock(&rq->lock);
+ if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
+ ts = next_job->submit_ts;
+ else
+ ts = drm_sched_rq_get_rr_ts(rq, entity);
+ drm_sched_rq_update_fifo_locked(entity, rq, ts);
+ spin_unlock(&rq->lock);
+ spin_unlock(&entity->lock);
}
/* Jobs and entities might have different lifecycles. Since we're
@@ -612,9 +627,9 @@ void drm_sched_entity_push_job(struct drm_sched_job
*sched_job)
spin_lock(&rq->lock);
drm_sched_rq_add_entity(rq, entity);
-
- if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
- drm_sched_rq_update_fifo_locked(entity, rq, submit_ts);
+ if (drm_sched_policy == DRM_SCHED_POLICY_RR)
+ submit_ts = entity->rr_ts;
+ drm_sched_rq_update_fifo_locked(entity, rq, submit_ts);
spin_unlock(&rq->lock);
spin_unlock(&entity->lock);
diff --git a/drivers/gpu/drm/scheduler/sched_main.c
b/drivers/gpu/drm/scheduler/sched_main.c
index 8b8c55b25762..8e62541b439a 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -185,7 +185,6 @@ static void drm_sched_rq_init(struct drm_sched_rq *rq,
spin_lock_init(&rq->lock);
INIT_LIST_HEAD(&rq->entities);
rq->rb_tree_root = RB_ROOT_CACHED;
- rq->current_entity = NULL;
rq->sched = sched;
}
@@ -231,74 +230,13 @@ void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
atomic_dec(rq->sched->score);
list_del_init(&entity->list);
- if (rq->current_entity == entity)
- rq->current_entity = NULL;
-
- if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
- drm_sched_rq_remove_fifo_locked(entity, rq);
+ drm_sched_rq_remove_fifo_locked(entity, rq);
spin_unlock(&rq->lock);
}
/**
- * drm_sched_rq_select_entity_rr - Select an entity which could provide a job
to run
- *
- * @sched: the gpu scheduler
- * @rq: scheduler run queue to check.
- *
- * Try to find the next ready entity.
- *
- * Return an entity if one is found; return an error-pointer (!NULL) if an
- * entity was ready, but the scheduler had insufficient credits to accommodate
- * its job; return NULL, if no ready entity was found.
- */
-static struct drm_sched_entity *
-drm_sched_rq_select_entity_rr(struct drm_gpu_scheduler *sched,
- struct drm_sched_rq *rq)
-{
- struct drm_sched_entity *entity;
-
- spin_lock(&rq->lock);
-
- entity = rq->current_entity;
- if (entity) {
- list_for_each_entry_continue(entity, &rq->entities, list) {
- if (drm_sched_entity_is_ready(entity))
- goto found;
- }
- }
-
- list_for_each_entry(entity, &rq->entities, list) {
- if (drm_sched_entity_is_ready(entity))
- goto found;
-
- if (entity == rq->current_entity)
- break;
- }
-
- spin_unlock(&rq->lock);
-
- return NULL;
-
-found:
- if (!drm_sched_can_queue(sched, entity)) {
- /*
- * If scheduler cannot take more jobs signal the caller to not
- * consider lower priority queues.
- */
- entity = ERR_PTR(-ENOSPC);
- } else {
- rq->current_entity = entity;
- reinit_completion(&entity->entity_idle);
- }
-
- spin_unlock(&rq->lock);
-
- return entity;
-}
-
-/**
- * drm_sched_rq_select_entity_fifo - Select an entity which provides a job to
run
+ * drm_sched_rq_select_entity - Select an entity which provides a job to run
*
* @sched: the gpu scheduler
* @rq: scheduler run queue to check.
@@ -310,8 +248,8 @@ drm_sched_rq_select_entity_rr(struct drm_gpu_scheduler
*sched,
* its job; return NULL, if no ready entity was found.
*/
static struct drm_sched_entity *
-drm_sched_rq_select_entity_fifo(struct drm_gpu_scheduler *sched,
- struct drm_sched_rq *rq)
+drm_sched_rq_select_entity(struct drm_gpu_scheduler *sched,
+ struct drm_sched_rq *rq)
{
struct rb_node *rb;
@@ -1093,15 +1031,13 @@ void drm_sched_wakeup(struct drm_gpu_scheduler *sched)
static struct drm_sched_entity *
drm_sched_select_entity(struct drm_gpu_scheduler *sched)
{
- struct drm_sched_entity *entity;
+ struct drm_sched_entity *entity = NULL;
int i;
/* Start with the highest priority.
*/
for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++) {
- entity = drm_sched_policy == DRM_SCHED_POLICY_FIFO ?
- drm_sched_rq_select_entity_fifo(sched,
sched->sched_rq[i]) :
- drm_sched_rq_select_entity_rr(sched,
sched->sched_rq[i]);
+ entity = drm_sched_rq_select_entity(sched, sched->sched_rq[i]);
if (entity)
break;
}
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index fb88301b3c45..8992393ed200 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -94,7 +94,8 @@ struct drm_sched_entity {
* @lock:
*
* Lock protecting the run-queue (@rq) to which this entity belongs,
- * @priority and the list of schedulers (@sched_list, @num_sched_list).
+ * @priority, the list of schedulers (@sched_list, @num_sched_list) and
+ * the @rr_ts field.
*/
spinlock_t lock;
@@ -142,6 +143,13 @@ struct drm_sched_entity {
*/
enum drm_sched_priority priority;
+ /**
+ * @rr_ts:
+ *
+ * Fake timestamp of the last popped job from the entity.
+ */
+ ktime_t rr_ts;
+
/**
* @job_queue: the list of jobs of this entity.
*/
@@ -239,8 +247,8 @@ struct drm_sched_entity {
* struct drm_sched_rq - queue of entities to be scheduled.
*
* @sched: the scheduler to which this rq belongs to.
- * @lock: protects @entities, @rb_tree_root and @current_entity.
- * @current_entity: the entity which is to be scheduled.
+ * @lock: protects @entities, @rb_tree_root and @rr_ts.
+ * @rr_ts: monotonically incrementing fake timestamp for RR mode