Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] Calling dma_fence_put() while holding the entity->lock spinlock 
introduces a risk of AB-BA lock inversion and deadlock with driver locks.
--

commit 21ecb5d3d71a1baa4ff6c29fb3ddc0deff8299e3
Author: Philipp Stanner <[email protected]>

drm/sched: Protect entity->last_scheduled with spinlock

This commit replaces the RCU protection and memory barriers used for
entity->last_scheduled with the existing entity->lock spinlock. It also
guards the spsc_queue_pop() call with the same lock as a preparatory step
for future cleanups.

> diff --git a/drivers/gpu/drm/scheduler/sched_entity.c 
> b/drivers/gpu/drm/scheduler/sched_entity.c
> index c51101ec70c16..95b2c48a604a6 100644
> --- a/drivers/gpu/drm/scheduler/sched_entity.c
> +++ b/drivers/gpu/drm/scheduler/sched_entity.c
[ ... ]
> @@ -523,18 +524,18 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct 
> drm_sched_entity *entity)
>       if (entity->guilty && atomic_read(entity->guilty))
>               dma_fence_set_error(&sched_job->s_fence->finished, -ECANCELED);
>  
> -     dma_fence_put(rcu_dereference_check(entity->last_scheduled, true));
> -     rcu_assign_pointer(entity->last_scheduled,
> -                        dma_fence_get(&sched_job->s_fence->finished));
> -
> -     /*
> -      * If the queue is empty we allow drm_sched_entity_select_rq() to
> -      * locklessly access ->last_scheduled. This only works if we set the
> -      * pointer before we dequeue and if we a write barrier here.
> +     spin_lock(&entity->lock);
> +     dma_fence_put(entity->last_scheduled);

[Severity: High]
Could calling dma_fence_put() while holding entity->lock introduce an AB-BA
lock inversion risk here?

If dropping the final reference to the scheduled fence invokes its release
callback, this can synchronously drop the reference to the underlying driver
hardware fence (fence->parent). When the hardware fence's reference count
drops to zero, the driver-specific release callback is invoked synchronously
while entity->lock is held.

Drivers commonly acquire their own internal locks (e.g., submission queue
locks) in their fence release callbacks. However, during job submission,
drivers typically hold these same internal locks before calling
drm_sched_entity_push_job(), which subsequently acquires entity->lock.
This reverse lock ordering might create a circular lock dependency.

Would it be safer to grab a local reference to entity->last_scheduled,
update the pointer, drop the spinlock, and then call dma_fence_put() on
the local reference outside the critical section?

> +     entity->last_scheduled = dma_fence_get(&sched_job->s_fence->finished);
> +
> +     /* A recent rework required taking the spinlock above. Since spsc_queue
> +      * is scheduled for removal as per the DRM-TODO-list, we access it here
> +      * locked already to prepare for that cleanup.
> +      *
> +      * TODO: Fully replace spsc_queue with a locked (h)list.
>        */
> -     smp_wmb();
> -
>       spsc_queue_pop(&entity->job_queue);
> +     spin_unlock(&entity->lock);
>  
>       drm_sched_rq_pop_entity(entity);
>

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=1

Reply via email to