From: Christian Koenig <christian.koenig@xxxxxxx> The spinlock was actually there to protect the rptr, but rptr was read outside of the locked area. v2: Keep the spinlock, looks like there is still something in the ih that doesn't like irqs enabled. Signed-off-by: Christian Koenig <christian.koenig@xxxxxxx> --- drivers/gpu/drm/radeon/evergreen.c | 5 ++--- drivers/gpu/drm/radeon/r600.c | 7 ++----- drivers/gpu/drm/radeon/radeon.h | 1 - drivers/gpu/drm/radeon/si.c | 6 ++---- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index dd3cea4..e4c3321 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2950,11 +2950,11 @@ int evergreen_irq_process(struct radeon_device *rdev) if (!rdev->ih.enabled || rdev->shutdown) return IRQ_NONE; + spin_lock_irqsave(&rdev->ih.lock, flags); wptr = evergreen_get_ih_wptr(rdev); rptr = rdev->ih.rptr; DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); - spin_lock_irqsave(&rdev->ih.lock, flags); if (rptr == wptr) { spin_unlock_irqrestore(&rdev->ih.lock, flags); return IRQ_NONE; @@ -2966,7 +2966,6 @@ restart_ih: /* display interrupts */ evergreen_irq_ack(rdev); - rdev->ih.wptr = wptr; while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; @@ -3267,7 +3266,7 @@ restart_ih: } /* make sure wptr hasn't changed while processing */ wptr = evergreen_get_ih_wptr(rdev); - if (wptr != rdev->ih.wptr) + if (wptr != rptr) goto restart_ih; if (queue_hotplug) schedule_work(&rdev->hotplug_work); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a8d8c44..e1861ac 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2921,7 +2921,6 @@ void r600_disable_interrupts(struct radeon_device *rdev) WREG32(IH_RB_RPTR, 0); WREG32(IH_RB_WPTR, 0); rdev->ih.enabled = false; - rdev->ih.wptr = 0; rdev->ih.rptr = 0; } @@ -3384,12 +3383,11 @@ int r600_irq_process(struct radeon_device *rdev) if (!rdev->msi_enabled) RREG32(IH_RB_WPTR); + spin_lock_irqsave(&rdev->ih.lock, flags); wptr = r600_get_ih_wptr(rdev); rptr = rdev->ih.rptr; DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); - spin_lock_irqsave(&rdev->ih.lock, flags); - if (rptr == wptr) { spin_unlock_irqrestore(&rdev->ih.lock, flags); return IRQ_NONE; @@ -3402,7 +3400,6 @@ restart_ih: /* display interrupts */ r600_irq_ack(rdev); - rdev->ih.wptr = wptr; while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; @@ -3558,7 +3555,7 @@ restart_ih: } /* make sure wptr hasn't changed while processing */ wptr = r600_get_ih_wptr(rdev); - if (wptr != rdev->ih.wptr) + if (wptr != rptr) goto restart_ih; if (queue_hotplug) schedule_work(&rdev->hotplug_work); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 618df9a..378d43b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -733,7 +733,6 @@ struct r600_ih { struct radeon_bo *ring_obj; volatile uint32_t *ring; unsigned rptr; - unsigned wptr; unsigned ring_size; uint64_t gpu_addr; uint32_t ptr_mask; diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 5ca8ef5..93da01c 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -3095,7 +3095,6 @@ static void si_disable_interrupts(struct radeon_device *rdev) WREG32(IH_RB_RPTR, 0); WREG32(IH_RB_WPTR, 0); rdev->ih.enabled = false; - rdev->ih.wptr = 0; rdev->ih.rptr = 0; } @@ -3518,11 +3517,11 @@ int si_irq_process(struct radeon_device *rdev) if (!rdev->ih.enabled || rdev->shutdown) return IRQ_NONE; + spin_lock_irqsave(&rdev->ih.lock, flags); wptr = si_get_ih_wptr(rdev); rptr = rdev->ih.rptr; DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr); - spin_lock_irqsave(&rdev->ih.lock, flags); if (rptr == wptr) { spin_unlock_irqrestore(&rdev->ih.lock, flags); return IRQ_NONE; @@ -3534,7 +3533,6 @@ restart_ih: /* display interrupts */ si_irq_ack(rdev); - rdev->ih.wptr = wptr; while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; @@ -3787,7 +3785,7 @@ restart_ih: } /* make sure wptr hasn't changed while processing */ wptr = si_get_ih_wptr(rdev); - if (wptr != rdev->ih.wptr) + if (wptr != rptr) goto restart_ih; if (queue_hotplug) schedule_work(&rdev->hotplug_work); -- 1.7.9.5 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel