From 0c38c5454b34af6746b63210f9eb43a40316333e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 5 Sep 2019 19:57:39 +0200 Subject: [PATCH] etnaviv: Command buffer realloc Reallocate the command stream buffer in case it is too small. The older kernel versions are limited to 64 kiB buffer, so limit the size to avoid oversized buffers. Signed-off-by: Marek Vasut --- src/etnaviv/drm/etnaviv_cmd_stream.c | 30 ++++++++++++++++++++++++++++ src/etnaviv/drm/etnaviv_drmif.h | 4 +++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/etnaviv/drm/etnaviv_cmd_stream.c b/src/etnaviv/drm/etnaviv_cmd_stream.c index 6a218ad0bf2..ef5143003ae 100644 --- a/src/etnaviv/drm/etnaviv_cmd_stream.c +++ b/src/etnaviv/drm/etnaviv_cmd_stream.c @@ -25,6 +25,7 @@ */ #include +#include #include "etnaviv_drmif.h" #include "etnaviv_priv.h" @@ -49,6 +50,35 @@ static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz) (x)->nr_ ## name ++; \ }) +void etna_cmd_stream_realloc(struct etna_cmd_stream *stream, size_t n) +{ + size_t size; + void *buffer; + + /* + * Increase the command buffer size by 1 kiB. Here we pick 1 kiB + * increment to prevent it from growing too much too quickly. + */ + size = ALIGN(stream->size + n, 1024); + + /* Command buffer is too big for older kernel versions */ + if (size >= 32768) + goto error; + + buffer = realloc(stream->buffer, size * 4); + if (!buffer) + goto error; + + stream->buffer = buffer; + stream->size = size; + + return; + +error: + WARN_MSG("command buffer too long, forcing flush."); + etna_cmd_stream_force_flush(stream); +} + static inline struct etna_cmd_stream_priv * etna_cmd_stream_priv(struct etna_cmd_stream *stream) { diff --git a/src/etnaviv/drm/etnaviv_drmif.h b/src/etnaviv/drm/etnaviv_drmif.h index 7fb01c8a654..ff08ab50dbc 100644 --- a/src/etnaviv/drm/etnaviv_drmif.h +++ b/src/etnaviv/drm/etnaviv_drmif.h @@ -154,10 +154,12 @@ static inline uint32_t etna_cmd_stream_avail(struct etna_cmd_stream *stream) return stream->size - stream->offset - END_CLEARANCE; } +void etna_cmd_stream_realloc(struct etna_cmd_stream *stream, size_t n); + static inline void etna_cmd_stream_reserve(struct etna_cmd_stream *stream, size_t n) { if (etna_cmd_stream_avail(stream) < n) - etna_cmd_stream_force_flush(stream); + etna_cmd_stream_realloc(stream, n); } static inline void etna_cmd_stream_emit(struct etna_cmd_stream *stream, uint32_t data) -- 2.30.2