Skip to content

Commit

Permalink
drm/sched: Fix dynamic job-flow control race
Browse files Browse the repository at this point in the history
Fixes a race condition reported here: #309 (comment)

The whole premise of lockless access to a single-producer-single-
consumer queue is that there is just a single producer and single
consumer.  That means we can't call drm_sched_can_queue() (which is
about queueing more work to the hw, not to the spsc queue) from
anywhere other than the consumer (wq).

This call in the producer is just an optimization to avoid scheduling
the consuming worker if it cannot yet queue more work to the hw.  It
is safe to drop this optimization to avoid the race condition.

Suggested-by: Asahi Lina <[email protected]>
Fixes: a78422e ("drm/sched: implement dynamic job-flow control")
Closes: #309
Cc: [email protected]
Signed-off-by: Rob Clark <[email protected]>
  • Loading branch information
robclark authored and jannau committed Sep 21, 2024
1 parent bcc9ecf commit b90e51e
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 8 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/scheduler/sched_entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
container_of(cb, struct drm_sched_entity, cb);

drm_sched_entity_clear_dep(f, cb);
drm_sched_wakeup(entity->rq->sched, entity);
drm_sched_wakeup(entity->rq->sched);
}

/**
Expand Down Expand Up @@ -612,7 +612,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
drm_sched_rq_update_fifo(entity, submit_ts);

drm_sched_wakeup(entity->rq->sched, entity);
drm_sched_wakeup(entity->rq->sched);
}
}
EXPORT_SYMBOL(drm_sched_entity_push_job);
7 changes: 2 additions & 5 deletions drivers/gpu/drm/scheduler/sched_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,15 +1022,12 @@ EXPORT_SYMBOL(drm_sched_job_cleanup);
/**
* drm_sched_wakeup - Wake up the scheduler if it is ready to queue
* @sched: scheduler instance
* @entity: the scheduler entity
*
* Wake up the scheduler if we can queue jobs.
*/
void drm_sched_wakeup(struct drm_gpu_scheduler *sched,
struct drm_sched_entity *entity)
void drm_sched_wakeup(struct drm_gpu_scheduler *sched)
{
if (drm_sched_can_queue(sched, entity))
drm_sched_run_job_queue(sched);
drm_sched_run_job_queue(sched);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion include/drm/gpu_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,

void drm_sched_tdr_queue_imm(struct drm_gpu_scheduler *sched);
void drm_sched_job_cleanup(struct drm_sched_job *job);
void drm_sched_wakeup(struct drm_gpu_scheduler *sched, struct drm_sched_entity *entity);
void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
bool drm_sched_wqueue_ready(struct drm_gpu_scheduler *sched);
void drm_sched_wqueue_stop(struct drm_gpu_scheduler *sched);
void drm_sched_wqueue_start(struct drm_gpu_scheduler *sched);
Expand Down

0 comments on commit b90e51e

Please sign in to comment.