Commit 4241db42 authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark

drm/msm/gpu: Add trace events for tracking GPU submissions

Add trace events to track the progress of a GPU submission
msm_gpu_submit occurs at the beginning of the submissions,
msm_gpu_submit_flush happens when the submission is put on
the ringbuffer and msm_submit_flush_retired is sent when
the operation is retired.

To make it easier to track the operations a unique sequence
number is assigned to each submission and displayed in each
event output so a human or a script can easily associate
the events related to a specific submission.
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 56869210
...@@ -90,7 +90,8 @@ msm-y := \ ...@@ -90,7 +90,8 @@ msm-y := \
msm_perf.o \ msm_perf.o \
msm_rd.o \ msm_rd.o \
msm_ringbuffer.o \ msm_ringbuffer.o \
msm_submitqueue.o msm_submitqueue.o \
msm_gpu_tracepoints.o
msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \ msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
disp/dpu1/dpu_dbg.o disp/dpu1/dpu_dbg.o
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "msm_gem.h" #include "msm_gem.h"
#include "msm_mmu.h" #include "msm_mmu.h"
#include "msm_gpu_trace.h"
#include "a6xx_gpu.h" #include "a6xx_gpu.h"
#include "a6xx_gmu.xml.h" #include "a6xx_gmu.xml.h"
...@@ -81,6 +82,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, ...@@ -81,6 +82,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
{ {
unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT; unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
struct msm_drm_private *priv = gpu->dev->dev_private; struct msm_drm_private *priv = gpu->dev->dev_private;
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
struct msm_ringbuffer *ring = submit->ring; struct msm_ringbuffer *ring = submit->ring;
unsigned int i; unsigned int i;
...@@ -138,6 +141,10 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, ...@@ -138,6 +141,10 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence))); OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
OUT_RING(ring, submit->seqno); OUT_RING(ring, submit->seqno);
trace_msm_gpu_submit_flush(submit,
gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L,
REG_A6XX_GMU_ALWAYS_ON_COUNTER_H));
a6xx_flush(gpu, ring); a6xx_flush(gpu, ring);
} }
......
...@@ -150,6 +150,7 @@ struct msm_gem_submit { ...@@ -150,6 +150,7 @@ struct msm_gem_submit {
struct msm_ringbuffer *ring; struct msm_ringbuffer *ring;
unsigned int nr_cmds; unsigned int nr_cmds;
unsigned int nr_bos; unsigned int nr_bos;
u32 ident; /* A "identifier" for the submit for logging */
struct { struct {
uint32_t type; uint32_t type;
uint32_t size; /* in dwords */ uint32_t size; /* in dwords */
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "msm_drv.h" #include "msm_drv.h"
#include "msm_gpu.h" #include "msm_gpu.h"
#include "msm_gem.h" #include "msm_gem.h"
#include "msm_gpu_trace.h"
/* /*
* Cmdstream submission: * Cmdstream submission:
...@@ -48,7 +49,6 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, ...@@ -48,7 +49,6 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
submit->dev = dev; submit->dev = dev;
submit->gpu = gpu; submit->gpu = gpu;
submit->fence = NULL; submit->fence = NULL;
submit->pid = get_pid(task_pid(current));
submit->cmd = (void *)&submit->bos[nr_bos]; submit->cmd = (void *)&submit->bos[nr_bos];
submit->queue = queue; submit->queue = queue;
submit->ring = gpu->rb[queue->prio]; submit->ring = gpu->rb[queue->prio];
...@@ -406,6 +406,7 @@ static void submit_cleanup(struct msm_gem_submit *submit) ...@@ -406,6 +406,7 @@ static void submit_cleanup(struct msm_gem_submit *submit)
int msm_ioctl_gem_submit(struct drm_device *dev, void *data, int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
struct drm_file *file) struct drm_file *file)
{ {
static atomic_t ident = ATOMIC_INIT(0);
struct msm_drm_private *priv = dev->dev_private; struct msm_drm_private *priv = dev->dev_private;
struct drm_msm_gem_submit *args = data; struct drm_msm_gem_submit *args = data;
struct msm_file_private *ctx = file->driver_priv; struct msm_file_private *ctx = file->driver_priv;
...@@ -416,9 +417,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -416,9 +417,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
struct msm_gpu_submitqueue *queue; struct msm_gpu_submitqueue *queue;
struct msm_ringbuffer *ring; struct msm_ringbuffer *ring;
int out_fence_fd = -1; int out_fence_fd = -1;
struct pid *pid = get_pid(task_pid(current));
unsigned i; unsigned i;
int ret; int ret, submitid;
if (!gpu) if (!gpu)
return -ENXIO; return -ENXIO;
...@@ -441,7 +442,12 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -441,7 +442,12 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
if (!queue) if (!queue)
return -ENOENT; return -ENOENT;
/* Get a unique identifier for the submission for logging purposes */
submitid = atomic_inc_return(&ident) - 1;
ring = gpu->rb[queue->prio]; ring = gpu->rb[queue->prio];
trace_msm_gpu_submit(pid_nr(pid), ring->id, submitid,
args->nr_bos, args->nr_cmds);
if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
in_fence = sync_file_get_fence(args->fence_fd); in_fence = sync_file_get_fence(args->fence_fd);
...@@ -478,6 +484,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -478,6 +484,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
goto out_unlock; goto out_unlock;
} }
submit->pid = pid;
submit->ident = submitid;
if (args->flags & MSM_SUBMIT_SUDO) if (args->flags & MSM_SUBMIT_SUDO)
submit->in_rb = true; submit->in_rb = true;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "msm_gem.h" #include "msm_gem.h"
#include "msm_mmu.h" #include "msm_mmu.h"
#include "msm_fence.h" #include "msm_fence.h"
#include "msm_gpu_trace.h"
#include <generated/utsrelease.h> #include <generated/utsrelease.h>
#include <linux/string_helpers.h> #include <linux/string_helpers.h>
...@@ -659,10 +660,28 @@ int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime, ...@@ -659,10 +660,28 @@ int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime,
* Cmdstream submission/retirement: * Cmdstream submission/retirement:
*/ */
static void retire_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
struct msm_gem_submit *submit)
{ {
int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
volatile struct msm_gpu_submit_stats *stats;
u64 elapsed, clock = 0;
int i; int i;
stats = &ring->memptrs->stats[index];
/* Convert 19.2Mhz alwayson ticks to nanoseconds for elapsed time */
elapsed = (stats->alwayson_end - stats->alwayson_start) * 10000;
do_div(elapsed, 192);
/* Calculate the clock frequency from the number of CP cycles */
if (elapsed) {
clock = (stats->cpcycles_end - stats->cpcycles_start) * 1000;
do_div(clock, elapsed);
}
trace_msm_gpu_submit_retired(submit, elapsed, clock,
stats->alwayson_start, stats->alwayson_end);
for (i = 0; i < submit->nr_bos; i++) { for (i = 0; i < submit->nr_bos; i++) {
struct msm_gem_object *msm_obj = submit->bos[i].obj; struct msm_gem_object *msm_obj = submit->bos[i].obj;
/* move to inactive: */ /* move to inactive: */
...@@ -690,7 +709,7 @@ static void retire_submits(struct msm_gpu *gpu) ...@@ -690,7 +709,7 @@ static void retire_submits(struct msm_gpu *gpu)
list_for_each_entry_safe(submit, tmp, &ring->submits, node) { list_for_each_entry_safe(submit, tmp, &ring->submits, node) {
if (dma_fence_is_signaled(submit->fence)) if (dma_fence_is_signaled(submit->fence))
retire_submit(gpu, submit); retire_submit(gpu, ring, submit);
} }
} }
} }
......
/* SPDX-License-Identifier: GPL-2.0 */
#if !defined(_MSM_GPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
#define _MSM_GPU_TRACE_H_
#include <linux/tracepoint.h>
#undef TRACE_SYSTEM
#define TRACE_SYSTEM drm_msm
#define TRACE_INCLUDE_FILE msm_gpu_trace
TRACE_EVENT(msm_gpu_submit,
TP_PROTO(pid_t pid, u32 ringid, u32 id, u32 nr_bos, u32 nr_cmds),
TP_ARGS(pid, ringid, id, nr_bos, nr_cmds),
TP_STRUCT__entry(
__field(pid_t, pid)
__field(u32, id)
__field(u32, ringid)
__field(u32, nr_cmds)
__field(u32, nr_bos)
),
TP_fast_assign(
__entry->pid = pid;
__entry->id = id;
__entry->ringid = ringid;
__entry->nr_bos = nr_bos;
__entry->nr_cmds = nr_cmds
),
TP_printk("id=%d pid=%d ring=%d bos=%d cmds=%d",
__entry->id, __entry->pid, __entry->ringid,
__entry->nr_bos, __entry->nr_cmds)
);
TRACE_EVENT(msm_gpu_submit_flush,
TP_PROTO(struct msm_gem_submit *submit, u64 ticks),
TP_ARGS(submit, ticks),
TP_STRUCT__entry(
__field(pid_t, pid)
__field(u32, id)
__field(u32, ringid)
__field(u32, seqno)
__field(u64, ticks)
),
TP_fast_assign(
__entry->pid = pid_nr(submit->pid);
__entry->id = submit->ident;
__entry->ringid = submit->ring->id;
__entry->seqno = submit->seqno;
__entry->ticks = ticks;
),
TP_printk("id=%d pid=%d ring=%d:%d ticks=%lld",
__entry->id, __entry->pid, __entry->ringid, __entry->seqno,
__entry->ticks)
);
TRACE_EVENT(msm_gpu_submit_retired,
TP_PROTO(struct msm_gem_submit *submit, u64 elapsed, u64 clock,
u64 start, u64 end),
TP_ARGS(submit, elapsed, clock, start, end),
TP_STRUCT__entry(
__field(pid_t, pid)
__field(u32, id)
__field(u32, ringid)
__field(u32, seqno)
__field(u64, elapsed)
__field(u64, clock)
__field(u64, start_ticks)
__field(u64, end_ticks)
),
TP_fast_assign(
__entry->pid = pid_nr(submit->pid);
__entry->id = submit->ident;
__entry->ringid = submit->ring->id;
__entry->seqno = submit->seqno;
__entry->elapsed = elapsed;
__entry->clock = clock;
__entry->start_ticks = start;
__entry->end_ticks = end;
),
TP_printk("id=%d pid=%d ring=%d:%d elapsed=%lld ns mhz=%lld start=%lld end=%lld",
__entry->id, __entry->pid, __entry->ringid, __entry->seqno,
__entry->elapsed, __entry->clock,
__entry->start_ticks, __entry->end_ticks)
);
#endif
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/msm
#include <trace/define_trace.h>
// SPDX-License-Identifier: GPL-2.0
#include "msm_gem.h"
#include "msm_ringbuffer.h"
#define CREATE_TRACE_POINTS
#include "msm_gpu_trace.h"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment