From b4fe945405e477cded91772b4fec854705443dd5 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Mon, 1 Feb 2010 19:11:16 +0200 Subject: drm/radeon: Fix memory allocation failures in the preKMS command stream checking. Allocation of single large block of memory may fail under memory presure. drm_buffer object can hold one large block of data in multiple independ pages which preents alloation failures. This patch converts all access to command stream to use drm_buffer interface. All direct access to array has to go tough drm_buffer functions to get correct pointer. Outputting the command stream to ring buffer needs to be awear of the split nature of drm_buffer. The output operation requires the new OUT_RING_DRM_BUFFER. Signed-off-by: Pauli Nieminen Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_drv.h | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon/radeon_drv.h') diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index b058316e311f..f6d20cee5705 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -312,9 +312,11 @@ typedef struct drm_radeon_buf_priv { u32 age; } drm_radeon_buf_priv_t; +struct drm_buffer; + typedef struct drm_radeon_kcmd_buffer { int bufsz; - char *buf; + struct drm_buffer *buffer; int nbox; struct drm_clip_rect __user *boxes; } drm_radeon_kcmd_buffer_t; @@ -2124,4 +2126,32 @@ extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); write &= mask; \ } while (0) +/** + * Copy given number of dwords from drm buffer to the ring buffer. + */ +#define OUT_RING_DRM_BUFFER(buf, sz) do { \ + int _size = (sz) * 4; \ + struct drm_buffer *_buf = (buf); \ + int _part_size; \ + while (_size > 0) { \ + _part_size = _size; \ + \ + if (write + _part_size/4 > mask) \ + _part_size = ((mask + 1) - write)*4; \ + \ + if (drm_buffer_index(_buf) + _part_size > PAGE_SIZE) \ + _part_size = PAGE_SIZE - drm_buffer_index(_buf);\ + \ + \ + \ + memcpy(ring + write, &_buf->data[drm_buffer_page(_buf)] \ + [drm_buffer_index(_buf)], _part_size); \ + \ + _size -= _part_size; \ + write = (write + _part_size/4) & mask; \ + drm_buffer_advance(_buf, _part_size); \ + } \ +} while (0) + + #endif /* __RADEON_DRV_H__ */ -- cgit v1.2.1