]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/sched: Remove idle entity from tree
authorTvrtko Ursulin <tvrtko.ursulin@igalia.com>
Fri, 17 Apr 2026 10:37:24 +0000 (11:37 +0100)
committerPhilipp Stanner <phasta@kernel.org>
Fri, 17 Apr 2026 12:43:28 +0000 (14:43 +0200)
There is no need to keep entities with no jobs in the tree so lets remove
it once the last job is consumed. This keeps the tree smaller which is
nicer and more efficient as entities are removed and re-added on every
popped job.

Apart from that, the upcoming fair scheduling algorithm will rely on the
tree only containing runnable entities.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Philipp Stanner <phasta@kernel.org>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Tested-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://patch.msgid.link/20260417103744.76020-10-tvrtko.ursulin@igalia.com
drivers/gpu/drm/scheduler/sched_rq.c

index 6948b342d26a7f834d978b0e48915b20a4a47c76..067083a59d59f6f27d8528ae32ea6422866df94a 100644 (file)
@@ -23,6 +23,9 @@ drm_sched_entity_compare_before(struct rb_node *a, const struct rb_node *b)
 static void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *entity,
                                            struct drm_sched_rq *rq)
 {
+       lockdep_assert_held(&entity->lock);
+       lockdep_assert_held(&rq->lock);
+
        if (!RB_EMPTY_NODE(&entity->rb_tree_node)) {
                rb_erase_cached(&entity->rb_tree_node, &rq->rb_tree_root);
                RB_CLEAR_NODE(&entity->rb_tree_node);
@@ -159,27 +162,30 @@ drm_sched_rq_next_rr_ts(struct drm_sched_rq *rq,
 void drm_sched_rq_pop_entity(struct drm_sched_entity *entity)
 {
        struct drm_sched_job *next_job;
+       struct drm_sched_rq *rq;
 
        /*
         * Update the entity's location in the min heap according to
         * the timestamp of the next job, if any.
         */
+       spin_lock(&entity->lock);
+       rq = entity->rq;
+       spin_lock(&rq->lock);
        next_job = drm_sched_entity_queue_peek(entity);
        if (next_job) {
-               struct drm_sched_rq *rq;
                ktime_t ts;
 
-               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_next_rr_ts(rq, entity);
+
                drm_sched_rq_update_fifo_locked(entity, rq, ts);
-               spin_unlock(&rq->lock);
-               spin_unlock(&entity->lock);
+       } else {
+               drm_sched_rq_remove_fifo_locked(entity, rq);
        }
+       spin_unlock(&rq->lock);
+       spin_unlock(&entity->lock);
 }
 
 /**