From fbe7451aa0ac00b79d098c07c040729d5894949e Mon Sep 17 00:00:00 2001 From: Markus Amsler Date: Tue, 1 Apr 2008 21:59:45 +0200 Subject: [PATCH] radeon: Fix possible lockup if ring buffer is running out of space If radeon_wait_ring returns -EBUSY, the GPU can lockup because, it's nowhere handled. That can happen if during the timeout the RADEON_CP_RB_RPTR_ADDR is not updated. For now it's better to have no timeout at all, as the GPU would lock up anyway. --- shared-core/radeon_cp.c | 23 ++++------------------- shared-core/radeon_drv.h | 2 +- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 89d2a24..24e0a2b 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -17606,36 +17606,21 @@ void radeon_freelist_reset(struct drm_device * dev) * CP command submission */ -int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) +void radeon_wait_ring(drm_radeon_private_t * dev_priv, int n) { drm_radeon_ring_buffer_t *ring = &dev_priv->ring; - int i; - u32 last_head = GET_RING_HEAD(dev_priv); - for (i = 0; i < dev_priv->usec_timeout; i++) { + do { u32 head = GET_RING_HEAD(dev_priv); ring->space = (head - ring->tail) * sizeof(u32); if (ring->space <= 0) ring->space += ring->size; if (ring->space > n) - return 0; - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if (head != last_head) - i = 0; - last_head = head; + return; DRM_UDELAY(1); - } - - /* FIXME: This return value is ignored in the BEGIN_RING macro! */ -#if RADEON_FIFO_DEBUG - radeon_status(dev_priv); - DRM_ERROR("failed!\n"); -#endif - return -EBUSY; + } while(1); } static int radeon_cp_get_buffers(struct drm_device *dev, diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index e8fb00d..6911dd0 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -360,7 +360,7 @@ extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); extern void radeon_freelist_reset(struct drm_device * dev); extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); -extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); +extern void radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); -- 1.5.4.5