drm/sched: Add bloody spinlocks
Subsystems (4)
Philipp Stanner
maintainercover drm/sched: Add bloody spinlocks
The scheduler wouldn't be the scheduler if there weren't functions like drm_sched_job_arm() being called probably a few thousand times per second without taking proper locks, just racing wildly.
This series adds the proper locks to drm_sched_job_init() and drm_sched_job_arm().
Philipp Stanner (2):
drm/sched: Use proper locks in drm_sched_job_arm() drm/sched: Use proper locks for drm_sched_job_init()
drivers/gpu/drm/scheduler/sched_main.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
Signature · 1 line
2.49.0
Philipp Stanner
maintainerPATCH 1/2 drm/sched: Use proper locks in drm_sched_job_arm()
drm_sched_job_arm() is just racing when dereferencing entity and runqueue.
Add the proper spinlocks.
--- drivers/gpu/drm/scheduler/sched_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/scheduler/sched_main.c +7 -1
@@ -859,10 +859,16 @@ void drm_sched_job_arm(struct drm_sched_job *job)BUG_ON (!entity);drm_sched_entity_select_rq (entity); + +spin_lock (&entity->lock); +spin_lock (&entity->rq->lock); sched = entity->rq->sched; +spin_unlock (&entity->rq->lock); + + job->s_priority = entity->priority; +spin_unlock (&entity->lock); job->sched = sched; - job->s_priority = entity->priority;drm_sched_fence_init (job->s_fence, job->entity); }
Signature · 1 line
2.49.0
Philipp Stanner
maintainerPATCH 2/2 drm/sched: Use proper locks for drm_sched_job_init()
In reply to Philipp Stannerdrm_sched_job_init() is just racing when checking an entity's runqueue, without taking the proper spinlock.
Add the lock.
--- drivers/gpu/drm/scheduler/sched_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/scheduler/sched_main.c +6 -1
@@ -799,7 +799,12 @@ int drm_sched_job_init(struct drm_sched_job *job, u32 credits, void *owner, uint64_t drm_client_id) { - if (!entity->rq) { + struct drm_sched_rq *rq; + +spin_lock (&entity->lock); + rq = entity->rq; +spin_unlock (&entity->lock); +if (!rq) {/* This will most likely be followed by missing frames * or worse--a blank screen--leave a trail in the * logs, so this can be debugged easier.
Signature · 1 line
2.49.0