diff options
author | Pauli Nieminen <suokkos@gmail.com> | 2010-02-01 12:11:16 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-22 18:46:20 -0500 |
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 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 { | |||
312 | u32 age; | 312 | u32 age; |
313 | } drm_radeon_buf_priv_t; | 313 | } drm_radeon_buf_priv_t; |
314 | 314 | ||
315 | struct drm_buffer; | ||
316 | |||
315 | typedef struct drm_radeon_kcmd_buffer { | 317 | typedef struct drm_radeon_kcmd_buffer { |
316 | int bufsz; | 318 | int bufsz; |
317 | char *buf; | 319 | struct drm_buffer *buffer; |
318 | int nbox; | 320 | int nbox; |
319 | struct drm_clip_rect __user *boxes; | 321 | struct drm_clip_rect __user *boxes; |
320 | } drm_radeon_kcmd_buffer_t; | 322 | } drm_radeon_kcmd_buffer_t; |
@@ -2124,4 +2126,32 @@ extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); | |||
2124 | write &= mask; \ | 2126 | write &= mask; \ |
2125 | } while (0) | 2127 | } while (0) |
2126 | 2128 | ||
2129 | /** | ||
2130 | * Copy given number of dwords from drm buffer to the ring buffer. | ||
2131 | */ | ||
2132 | #define OUT_RING_DRM_BUFFER(buf, sz) do { \ | ||
2133 | int _size = (sz) * 4; \ | ||
2134 | struct drm_buffer *_buf = (buf); \ | ||
2135 | int _part_size; \ | ||
2136 | while (_size > 0) { \ | ||
2137 | _part_size = _size; \ | ||
2138 | \ | ||
2139 | if (write + _part_size/4 > mask) \ | ||
2140 | _part_size = ((mask + 1) - write)*4; \ | ||
2141 | \ | ||
2142 | if (drm_buffer_index(_buf) + _part_size > PAGE_SIZE) \ | ||
2143 | _part_size = PAGE_SIZE - drm_buffer_index(_buf);\ | ||
2144 | \ | ||
2145 | \ | ||
2146 | \ | ||
2147 | memcpy(ring + write, &_buf->data[drm_buffer_page(_buf)] \ | ||
2148 | [drm_buffer_index(_buf)], _part_size); \ | ||
2149 | \ | ||
2150 | _size -= _part_size; \ | ||
2151 | write = (write + _part_size/4) & mask; \ | ||
2152 | drm_buffer_advance(_buf, _part_size); \ | ||
2153 | } \ | ||
2154 | } while (0) | ||
2155 | |||
2156 | |||
2127 | #endif /* __RADEON_DRV_H__ */ | 2157 | #endif /* __RADEON_DRV_H__ */ |