summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@igalia.com>2026-04-17 13:37:24 +0300
committerPhilipp Stanner <phasta@kernel.org>2026-04-17 15:43:28 +0300
commit8637ddeeb4bbd48dafa1be316d8296e8d49e7521 (patch)
tree4b6aa89f1c717fed7ff128e4b209d1b4b7f1cfdb
parentfd177135f0e62344f5d0ad3b12d40f8f7e5cdaab (diff)
downloadlinux-8637ddeeb4bbd48dafa1be316d8296e8d49e7521.tar.xz
drm/sched: Remove idle entity from tree
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
-rw-r--r--drivers/gpu/drm/scheduler/sched_rq.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/gpu/drm/scheduler/sched_rq.c b/drivers/gpu/drm/scheduler/sched_rq.c
index 6948b342d26a..067083a59d59 100644
--- a/drivers/gpu/drm/scheduler/sched_rq.c
+++ b/drivers/gpu/drm/scheduler/sched_rq.c
@@ -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);
}
/**