drm/msm/adreno: Add ringbuffer data to the GPU state

Add the contents of each ringbuffer to the GPU state and dump the
data in the crash file encoded with ascii85. To save space only
the used portions of the ringbuffer are dumped.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Jordan Crouse
2018-07-24 10:33:29 -06:00
committed by Rob Clark
parent bcf1d9fa5d
commit 43a56687d1
3 changed files with 48 additions and 0 deletions

View File

@@ -17,6 +17,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/ascii85.h>
#include <linux/pm_opp.h>
#include "adreno_gpu.h"
#include "msm_gem.h"
@@ -383,11 +384,29 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
do_gettimeofday(&state->time);
for (i = 0; i < gpu->nr_rings; i++) {
int size = 0, j;
state->ring[i].fence = gpu->rb[i]->memptrs->fence;
state->ring[i].iova = gpu->rb[i]->iova;
state->ring[i].seqno = gpu->rb[i]->seqno;
state->ring[i].rptr = get_rptr(adreno_gpu, gpu->rb[i]);
state->ring[i].wptr = get_wptr(gpu->rb[i]);
/* Copy at least 'wptr' dwords of the data */
size = state->ring[i].wptr;
/* After wptr find the last non zero dword to save space */
for (j = state->ring[i].wptr; j < MSM_GPU_RINGBUFFER_SZ >> 2; j++)
if (gpu->rb[i]->start[j])
size = j + 1;
if (size) {
state->ring[i].data = kmalloc(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;
}
}
}
/* Count the number of registers */
@@ -418,9 +437,13 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
static void adreno_gpu_state_destroy(struct kref *kref)
{
int i;
struct msm_gpu_state *state = container_of(kref,
struct msm_gpu_state, ref);
for (i = 0; i < ARRAY_SIZE(state->ring); i++)
kfree(state->ring[i].data);
kfree(state->comm);
kfree(state->cmd);
kfree(state->registers);
@@ -461,6 +484,22 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
drm_printf(p, " retired-fence: %d\n", state->ring[i].fence);
drm_printf(p, " rptr: %d\n", state->ring[i].rptr);
drm_printf(p, " wptr: %d\n", state->ring[i].wptr);
drm_printf(p, " size: %d\n", MSM_GPU_RINGBUFFER_SZ);
if (state->ring[i].data && state->ring[i].data_size) {
u32 *ptr = (u32 *) state->ring[i].data;
char out[ASCII85_BUFSZ];
long len = ascii85_encode_len(state->ring[i].data_size);
int j;
drm_printf(p, " data: !!ascii85 |\n");
drm_printf(p, " ");
for (j = 0; j < len; j++)
drm_printf(p, ascii85_encode(ptr[j], out));
drm_printf(p, "\n");
}
}
drm_puts(p, "registers:\n");