diff options
author | Pauli Nieminen <suokkos@gmail.com> | 2010-02-01 19:11:16 +0200 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-23 09:46:20 +1000 |
commit | b4fe945405e477cded91772b4fec854705443dd5 (patch) | |
tree | 4fb175511947cfd9980ca74413692f96561d1512 /drivers/gpu/drm/radeon/radeon_drv.h | |
parent | 7a9f0dd9c49425e2b0e39ada4757bc7a38c84873 (diff) |
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 <suokkos@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_drv.h')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.h | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index b058316e311..f6d20cee570 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__ */ |