Skip to content

Commit

Permalink
drm/v3d: Create a struct to store the GPU stats
Browse files Browse the repository at this point in the history
This will make it easier to instantiate the GPU stats variables and it
will create a structure where we can store all the variables that refer
to GPU stats.

Note that, when we created the struct `v3d_stats`, we renamed
`jobs_sent` to `jobs_completed`. This better express the semantics of
the variable, as we are only accounting jobs that have been completed.

Signed-off-by: Maíra Canal <[email protected]>
Reviewed-by: Tvrtko Ursulin <[email protected]>
Reviewed-by: Jose Maria Casanova Crespo <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
  • Loading branch information
mairacanal committed Apr 23, 2024
1 parent 52ce977 commit b136b19
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 32 deletions.
15 changes: 7 additions & 8 deletions drivers/gpu/drm/v3d/v3d_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,12 @@ v3d_open(struct drm_device *dev, struct drm_file *file)
v3d_priv->v3d = v3d;

for (i = 0; i < V3D_MAX_QUEUES; i++) {
v3d_priv->enabled_ns[i] = 0;
v3d_priv->start_ns[i] = 0;
v3d_priv->jobs_sent[i] = 0;

sched = &v3d->queue[i].sched;
drm_sched_entity_init(&v3d_priv->sched_entity[i],
DRM_SCHED_PRIORITY_NORMAL, &sched,
1, NULL);

memset(&v3d_priv->stats[i], 0, sizeof(v3d_priv->stats[i]));
}

v3d_perfmon_open_file(v3d_priv);
Expand Down Expand Up @@ -151,20 +149,21 @@ static void v3d_show_fdinfo(struct drm_printer *p, struct drm_file *file)
enum v3d_queue queue;

for (queue = 0; queue < V3D_MAX_QUEUES; queue++) {
struct v3d_stats *stats = &file_priv->stats[queue];

/* Note that, in case of a GPU reset, the time spent during an
* attempt of executing the job is not computed in the runtime.
*/
drm_printf(p, "drm-engine-%s: \t%llu ns\n",
v3d_queue_to_string(queue),
file_priv->start_ns[queue] ? file_priv->enabled_ns[queue]
+ timestamp - file_priv->start_ns[queue]
: file_priv->enabled_ns[queue]);
stats->start_ns ? stats->enabled_ns + timestamp - stats->start_ns
: stats->enabled_ns);

/* Note that we only count jobs that completed. Therefore, jobs
* that were resubmitted due to a GPU reset are not computed.
*/
drm_printf(p, "v3d-jobs-%s: \t%llu jobs\n",
v3d_queue_to_string(queue), file_priv->jobs_sent[queue]);
v3d_queue_to_string(queue), stats->jobs_completed);
}
}

Expand Down
18 changes: 10 additions & 8 deletions drivers/gpu/drm/v3d/v3d_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,20 @@ static inline char *v3d_queue_to_string(enum v3d_queue queue)
return "UNKNOWN";
}

struct v3d_stats {
u64 start_ns;
u64 enabled_ns;
u64 jobs_completed;
};

struct v3d_queue_state {
struct drm_gpu_scheduler sched;

u64 fence_context;
u64 emit_seqno;

u64 start_ns;
u64 enabled_ns;
u64 jobs_sent;
/* Stores the GPU stats for this queue in the global context. */
struct v3d_stats stats;
};

/* Performance monitor object. The perform lifetime is controlled by userspace
Expand Down Expand Up @@ -188,11 +193,8 @@ struct v3d_file_priv {

struct drm_sched_entity sched_entity[V3D_MAX_QUEUES];

u64 start_ns[V3D_MAX_QUEUES];

u64 enabled_ns[V3D_MAX_QUEUES];

u64 jobs_sent[V3D_MAX_QUEUES];
/* Stores the GPU stats for a specific queue for this fd. */
struct v3d_stats stats[V3D_MAX_QUEUES];
};

struct v3d_bo {
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/v3d/v3d_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@ v3d_gem_init(struct drm_device *dev)
int ret, i;

for (i = 0; i < V3D_MAX_QUEUES; i++) {
v3d->queue[i].fence_context = dma_fence_context_alloc(1);
v3d->queue[i].start_ns = 0;
v3d->queue[i].enabled_ns = 0;
v3d->queue[i].jobs_sent = 0;
struct v3d_queue_state *queue = &v3d->queue[i];

queue->fence_context = dma_fence_context_alloc(1);
memset(&queue->stats, 0, sizeof(queue->stats));
}

spin_lock_init(&v3d->mm_lock);
Expand Down
20 changes: 12 additions & 8 deletions drivers/gpu/drm/v3d/v3d_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,26 +110,30 @@ v3d_job_start_stats(struct v3d_job *job, enum v3d_queue queue)
{
struct v3d_dev *v3d = job->v3d;
struct v3d_file_priv *file = job->file->driver_priv;
struct v3d_stats *global_stats = &v3d->queue[queue].stats;
struct v3d_stats *local_stats = &file->stats[queue];
u64 now = local_clock();

file->start_ns[queue] = now;
v3d->queue[queue].start_ns = now;
local_stats->start_ns = now;
global_stats->start_ns = now;
}

void
v3d_job_update_stats(struct v3d_job *job, enum v3d_queue queue)
{
struct v3d_dev *v3d = job->v3d;
struct v3d_file_priv *file = job->file->driver_priv;
struct v3d_stats *global_stats = &v3d->queue[queue].stats;
struct v3d_stats *local_stats = &file->stats[queue];
u64 now = local_clock();

file->enabled_ns[queue] += now - file->start_ns[queue];
file->jobs_sent[queue]++;
file->start_ns[queue] = 0;
local_stats->enabled_ns += now - local_stats->start_ns;
local_stats->jobs_completed++;
local_stats->start_ns = 0;

v3d->queue[queue].enabled_ns += now - v3d->queue[queue].start_ns;
v3d->queue[queue].jobs_sent++;
v3d->queue[queue].start_ns = 0;
global_stats->enabled_ns += now - global_stats->start_ns;
global_stats->jobs_completed++;
global_stats->start_ns = 0;
}

static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job)
Expand Down
10 changes: 6 additions & 4 deletions drivers/gpu/drm/v3d/v3d_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ gpu_stats_show(struct device *dev, struct device_attribute *attr, char *buf)
len += sysfs_emit(buf, "queue\ttimestamp\tjobs\truntime\n");

for (queue = 0; queue < V3D_MAX_QUEUES; queue++) {
if (v3d->queue[queue].start_ns)
active_runtime = timestamp - v3d->queue[queue].start_ns;
struct v3d_stats *stats = &v3d->queue[queue].stats;

if (stats->start_ns)
active_runtime = timestamp - stats->start_ns;
else
active_runtime = 0;

Expand All @@ -39,8 +41,8 @@ gpu_stats_show(struct device *dev, struct device_attribute *attr, char *buf)
len += sysfs_emit_at(buf, len, "%s\t%llu\t%llu\t%llu\n",
v3d_queue_to_string(queue),
timestamp,
v3d->queue[queue].jobs_sent,
v3d->queue[queue].enabled_ns + active_runtime);
stats->jobs_completed,
stats->enabled_ns + active_runtime);
}

return len;
Expand Down

0 comments on commit b136b19

Please sign in to comment.