diff options
-rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.c | 82 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.h | 2 |
2 files changed, 63 insertions, 21 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 20c86e2369f3..bbd7350a7f39 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -398,7 +398,7 @@ int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state) size = j + 1; if (size) { - state->ring[i].data = kmalloc(size << 2, GFP_KERNEL); + state->ring[i].data = kvmalloc(size << 2, GFP_KERNEL); if (state->ring[i].data) { memcpy(state->ring[i].data, gpu->rb[i]->start, size << 2); state->ring[i].data_size = size << 2; @@ -441,7 +441,7 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state) int i; for (i = 0; i < ARRAY_SIZE(state->ring); i++) - kfree(state->ring[i].data); + kvfree(state->ring[i].data); for (i = 0; state->bos && i < state->nr_bos; i++) kvfree(state->bos[i].data); @@ -471,34 +471,74 @@ int adreno_gpu_state_put(struct msm_gpu_state *state) #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) -static void adreno_show_object(struct drm_printer *p, u32 *ptr, int len) +static char *adreno_gpu_ascii85_encode(u32 *src, size_t len) { + void *buf; + size_t buf_itr = 0, buffer_size; char out[ASCII85_BUFSZ]; - long l, datalen, i; + long l; + int i; - if (!ptr || !len) - return; + if (!src || !len) + return NULL; + + l = ascii85_encode_len(len); /* - * Only dump the non-zero part of the buffer - rarely will any data - * completely fill the entire allocated size of the buffer + * Ascii85 outputs either a 5 byte string or a 1 byte string. So we + * account for the worst case of 5 bytes per dword plus the 1 for '\0' */ - for (datalen = 0, i = 0; i < len >> 2; i++) { - if (ptr[i]) - datalen = (i << 2) + 1; - } + buffer_size = (l * 5) + 1; + + buf = kvmalloc(buffer_size, GFP_KERNEL); + if (!buf) + return NULL; - /* Skip printing the object if it is empty */ - if (datalen == 0) + for (i = 0; i < l; i++) + buf_itr += snprintf(buf + buf_itr, buffer_size - buf_itr, "%s", + ascii85_encode(src[i], out)); + + return buf; +} + +/* len is expected to be in bytes */ +static void adreno_show_object(struct drm_printer *p, void **ptr, int len, + bool *encoded) +{ + if (!*ptr || !len) return; - l = ascii85_encode_len(datalen); + if (!*encoded) { + long datalen, i; + u32 *buf = *ptr; + + /* + * Only dump the non-zero part of the buffer - rarely will + * any data completely fill the entire allocated size of + * the buffer. + */ + for (datalen = 0, i = 0; i < len >> 2; i++) + if (buf[i]) + datalen = ((i + 1) << 2); + + /* + * If we reach here, then the originally captured binary buffer + * will be replaced with the ascii85 encoded string + */ + *ptr = adreno_gpu_ascii85_encode(buf, datalen); + + kvfree(buf); + + *encoded = true; + } + + if (!*ptr) + return; drm_puts(p, " data: !!ascii85 |\n"); drm_puts(p, " "); - for (i = 0; i < l; i++) - drm_puts(p, ascii85_encode(ptr[i], out)); + drm_puts(p, *ptr); drm_puts(p, "\n"); } @@ -530,8 +570,8 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, drm_printf(p, " wptr: %d\n", state->ring[i].wptr); drm_printf(p, " size: %d\n", MSM_GPU_RINGBUFFER_SZ); - adreno_show_object(p, state->ring[i].data, - state->ring[i].data_size); + adreno_show_object(p, &state->ring[i].data, + state->ring[i].data_size, &state->ring[i].encoded); } if (state->bos) { @@ -542,8 +582,8 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, state->bos[i].iova); drm_printf(p, " size: %zd\n", state->bos[i].size); - adreno_show_object(p, state->bos[i].data, - state->bos[i].size); + adreno_show_object(p, &state->bos[i].data, + state->bos[i].size, &state->bos[i].encoded); } } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index f82bac086666..efb49bb64191 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -187,6 +187,7 @@ struct msm_gpu_state_bo { u64 iova; size_t size; void *data; + bool encoded; }; struct msm_gpu_state { @@ -201,6 +202,7 @@ struct msm_gpu_state { u32 wptr; void *data; int data_size; + bool encoded; } ring[MSM_GPU_MAX_RINGS]; int nr_registers; |