mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 12:52:29 -04:00
drm/amdgpu/userq: fix lock missing for userq fence error set
amdgpu_userq_fence_driver() and amdgpu_userq_fence_driver_destroy() don't acquire the dma_fence spinlock, so locking the dma_fence lock before test the signaled state and set error state to avoid missing lock assert error. Signed-off-by: Prike Liang <Prike.Liang@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
520e345ffe
commit
a04ea08ddb
@@ -191,14 +191,15 @@ void amdgpu_userq_fence_driver_destroy(struct kref *ref)
|
||||
struct dma_fence *f;
|
||||
|
||||
spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
|
||||
lockdep_assert_held(&fence_drv->fence_list_lock);
|
||||
list_for_each_entry_safe(fence, tmp, &fence_drv->fences, link) {
|
||||
f = &fence->base;
|
||||
|
||||
if (!dma_fence_is_signaled(f)) {
|
||||
spin_lock(dma_fence_spinlock(f));
|
||||
if (!dma_fence_is_signaled_locked(f)) {
|
||||
dma_fence_set_error(f, -ECANCELED);
|
||||
dma_fence_signal(f);
|
||||
dma_fence_signal_locked(f);
|
||||
}
|
||||
|
||||
spin_unlock(dma_fence_spinlock(f));
|
||||
list_del(&fence->link);
|
||||
dma_fence_put(f);
|
||||
}
|
||||
@@ -423,11 +424,16 @@ amdgpu_userq_fence_driver_set_error(struct amdgpu_userq_fence *fence,
|
||||
struct dma_fence *f;
|
||||
|
||||
spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
|
||||
|
||||
lockdep_assert_held(&fence_drv->fence_list_lock);
|
||||
f = rcu_dereference_protected(&fence->base,
|
||||
lockdep_is_held(&fence_drv->fence_list_lock));
|
||||
if (f && !dma_fence_is_signaled_locked(f))
|
||||
dma_fence_set_error(f, error);
|
||||
if (f) {
|
||||
/* nest f->lock inside fence_list_lock */
|
||||
spin_lock(dma_fence_spinlock(f));
|
||||
if (!dma_fence_is_signaled_locked(f))
|
||||
dma_fence_set_error(f, error);
|
||||
spin_unlock(dma_fence_spinlock(f));
|
||||
}
|
||||
spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user