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); } /**