Skip to content

Commit

Permalink
drm/v3d: Create two functions to update all GPU stats variables
Browse files Browse the repository at this point in the history
Currently, we manually perform all operations to update the GPU stats
variables. Apart from the code repetition, this is very prone to errors,
as we can see on commit 35f4f8c ("drm/v3d: Don't increment
`enabled_ns` twice").

Therefore, create two functions to manage updating all GPU stats
variables. Now, the jobs only need to call for `v3d_job_update_stats()`
when the job is done and `v3d_job_start_stats()` when starting the job.

Co-developed-by: Tvrtko Ursulin <tursulin@igalia.com>
Signed-off-by: Tvrtko Ursulin <tursulin@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Reviewed-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240420213632.339941-3-mcanal@igalia.com
  • Loading branch information
Maíra Canal committed Apr 23, 2024
1 parent a6325ad commit 52ce977
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 89 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/v3d/v3d_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ void v3d_mmu_insert_ptes(struct v3d_bo *bo);
void v3d_mmu_remove_ptes(struct v3d_bo *bo);

/* v3d_sched.c */
void v3d_job_update_stats(struct v3d_job *job, enum v3d_queue queue);
int v3d_sched_init(struct v3d_dev *v3d);
void v3d_sched_fini(struct v3d_dev *v3d);

Expand Down
48 changes: 4 additions & 44 deletions drivers/gpu/drm/v3d/v3d_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,8 @@ v3d_irq(int irq, void *arg)
if (intsts & V3D_INT_FLDONE) {
struct v3d_fence *fence =
to_v3d_fence(v3d->bin_job->base.irq_fence);
struct v3d_file_priv *file = v3d->bin_job->base.file->driver_priv;
u64 runtime = local_clock() - file->start_ns[V3D_BIN];

file->jobs_sent[V3D_BIN]++;
v3d->queue[V3D_BIN].jobs_sent++;

file->start_ns[V3D_BIN] = 0;
v3d->queue[V3D_BIN].start_ns = 0;

file->enabled_ns[V3D_BIN] += runtime;
v3d->queue[V3D_BIN].enabled_ns += runtime;

v3d_job_update_stats(&v3d->bin_job->base, V3D_BIN);
trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base);
status = IRQ_HANDLED;
Expand All @@ -122,18 +112,8 @@ v3d_irq(int irq, void *arg)
if (intsts & V3D_INT_FRDONE) {
struct v3d_fence *fence =
to_v3d_fence(v3d->render_job->base.irq_fence);
struct v3d_file_priv *file = v3d->render_job->base.file->driver_priv;
u64 runtime = local_clock() - file->start_ns[V3D_RENDER];

file->jobs_sent[V3D_RENDER]++;
v3d->queue[V3D_RENDER].jobs_sent++;

file->start_ns[V3D_RENDER] = 0;
v3d->queue[V3D_RENDER].start_ns = 0;

file->enabled_ns[V3D_RENDER] += runtime;
v3d->queue[V3D_RENDER].enabled_ns += runtime;

v3d_job_update_stats(&v3d->render_job->base, V3D_RENDER);
trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base);
status = IRQ_HANDLED;
Expand All @@ -142,18 +122,8 @@ v3d_irq(int irq, void *arg)
if (intsts & V3D_INT_CSDDONE(v3d->ver)) {
struct v3d_fence *fence =
to_v3d_fence(v3d->csd_job->base.irq_fence);
struct v3d_file_priv *file = v3d->csd_job->base.file->driver_priv;
u64 runtime = local_clock() - file->start_ns[V3D_CSD];

file->jobs_sent[V3D_CSD]++;
v3d->queue[V3D_CSD].jobs_sent++;

file->start_ns[V3D_CSD] = 0;
v3d->queue[V3D_CSD].start_ns = 0;

file->enabled_ns[V3D_CSD] += runtime;
v3d->queue[V3D_CSD].enabled_ns += runtime;

v3d_job_update_stats(&v3d->csd_job->base, V3D_CSD);
trace_v3d_csd_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base);
status = IRQ_HANDLED;
Expand Down Expand Up @@ -189,18 +159,8 @@ v3d_hub_irq(int irq, void *arg)
if (intsts & V3D_HUB_INT_TFUC) {
struct v3d_fence *fence =
to_v3d_fence(v3d->tfu_job->base.irq_fence);
struct v3d_file_priv *file = v3d->tfu_job->base.file->driver_priv;
u64 runtime = local_clock() - file->start_ns[V3D_TFU];

file->jobs_sent[V3D_TFU]++;
v3d->queue[V3D_TFU].jobs_sent++;

file->start_ns[V3D_TFU] = 0;
v3d->queue[V3D_TFU].start_ns = 0;

file->enabled_ns[V3D_TFU] += runtime;
v3d->queue[V3D_TFU].enabled_ns += runtime;

v3d_job_update_stats(&v3d->tfu_job->base, V3D_TFU);
trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base);
status = IRQ_HANDLED;
Expand Down
80 changes: 35 additions & 45 deletions drivers/gpu/drm/v3d/v3d_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,37 @@ v3d_switch_perfmon(struct v3d_dev *v3d, struct v3d_job *job)
v3d_perfmon_start(v3d, job->perfmon);
}

static void
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;
u64 now = local_clock();

file->start_ns[queue] = now;
v3d->queue[queue].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;
u64 now = local_clock();

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

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

static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job)
{
struct v3d_bin_job *job = to_bin_job(sched_job);
struct v3d_dev *v3d = job->base.v3d;
struct v3d_file_priv *file = job->base.file->driver_priv;
struct drm_device *dev = &v3d->drm;
struct dma_fence *fence;
unsigned long irqflags;
Expand Down Expand Up @@ -141,9 +167,7 @@ static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job)
trace_v3d_submit_cl(dev, false, to_v3d_fence(fence)->seqno,
job->start, job->end);

file->start_ns[V3D_BIN] = local_clock();
v3d->queue[V3D_BIN].start_ns = file->start_ns[V3D_BIN];

v3d_job_start_stats(&job->base, V3D_BIN);
v3d_switch_perfmon(v3d, &job->base);

/* Set the current and end address of the control list.
Expand All @@ -168,7 +192,6 @@ static struct dma_fence *v3d_render_job_run(struct drm_sched_job *sched_job)
{
struct v3d_render_job *job = to_render_job(sched_job);
struct v3d_dev *v3d = job->base.v3d;
struct v3d_file_priv *file = job->base.file->driver_priv;
struct drm_device *dev = &v3d->drm;
struct dma_fence *fence;

Expand Down Expand Up @@ -196,9 +219,7 @@ static struct dma_fence *v3d_render_job_run(struct drm_sched_job *sched_job)
trace_v3d_submit_cl(dev, true, to_v3d_fence(fence)->seqno,
job->start, job->end);

file->start_ns[V3D_RENDER] = local_clock();
v3d->queue[V3D_RENDER].start_ns = file->start_ns[V3D_RENDER];

v3d_job_start_stats(&job->base, V3D_RENDER);
v3d_switch_perfmon(v3d, &job->base);

/* XXX: Set the QCFG */
Expand All @@ -217,7 +238,6 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job)
{
struct v3d_tfu_job *job = to_tfu_job(sched_job);
struct v3d_dev *v3d = job->base.v3d;
struct v3d_file_priv *file = job->base.file->driver_priv;
struct drm_device *dev = &v3d->drm;
struct dma_fence *fence;

Expand All @@ -232,8 +252,7 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job)

trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno);

file->start_ns[V3D_TFU] = local_clock();
v3d->queue[V3D_TFU].start_ns = file->start_ns[V3D_TFU];
v3d_job_start_stats(&job->base, V3D_TFU);

V3D_WRITE(V3D_TFU_IIA(v3d->ver), job->args.iia);
V3D_WRITE(V3D_TFU_IIS(v3d->ver), job->args.iis);
Expand All @@ -260,7 +279,6 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)
{
struct v3d_csd_job *job = to_csd_job(sched_job);
struct v3d_dev *v3d = job->base.v3d;
struct v3d_file_priv *file = job->base.file->driver_priv;
struct drm_device *dev = &v3d->drm;
struct dma_fence *fence;
int i, csd_cfg0_reg, csd_cfg_reg_count;
Expand All @@ -279,9 +297,7 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)

trace_v3d_submit_csd(dev, to_v3d_fence(fence)->seqno);

file->start_ns[V3D_CSD] = local_clock();
v3d->queue[V3D_CSD].start_ns = file->start_ns[V3D_CSD];

v3d_job_start_stats(&job->base, V3D_CSD);
v3d_switch_perfmon(v3d, &job->base);

csd_cfg0_reg = V3D_CSD_QUEUED_CFG0(v3d->ver);
Expand Down Expand Up @@ -530,8 +546,6 @@ v3d_cpu_job_run(struct drm_sched_job *sched_job)
{
struct v3d_cpu_job *job = to_cpu_job(sched_job);
struct v3d_dev *v3d = job->base.v3d;
struct v3d_file_priv *file = job->base.file->driver_priv;
u64 runtime;

v3d->cpu_job = job;

Expand All @@ -540,25 +554,13 @@ v3d_cpu_job_run(struct drm_sched_job *sched_job)
return NULL;
}

file->start_ns[V3D_CPU] = local_clock();
v3d->queue[V3D_CPU].start_ns = file->start_ns[V3D_CPU];

v3d_job_start_stats(&job->base, V3D_CPU);
trace_v3d_cpu_job_begin(&v3d->drm, job->job_type);

cpu_job_function[job->job_type](job);

trace_v3d_cpu_job_end(&v3d->drm, job->job_type);

runtime = local_clock() - file->start_ns[V3D_CPU];

file->enabled_ns[V3D_CPU] += runtime;
v3d->queue[V3D_CPU].enabled_ns += runtime;

file->jobs_sent[V3D_CPU]++;
v3d->queue[V3D_CPU].jobs_sent++;

file->start_ns[V3D_CPU] = 0;
v3d->queue[V3D_CPU].start_ns = 0;
v3d_job_update_stats(&job->base, V3D_CPU);

return NULL;
}
Expand All @@ -568,24 +570,12 @@ v3d_cache_clean_job_run(struct drm_sched_job *sched_job)
{
struct v3d_job *job = to_v3d_job(sched_job);
struct v3d_dev *v3d = job->v3d;
struct v3d_file_priv *file = job->file->driver_priv;
u64 runtime;

file->start_ns[V3D_CACHE_CLEAN] = local_clock();
v3d->queue[V3D_CACHE_CLEAN].start_ns = file->start_ns[V3D_CACHE_CLEAN];
v3d_job_start_stats(job, V3D_CACHE_CLEAN);

v3d_clean_caches(v3d);

runtime = local_clock() - file->start_ns[V3D_CACHE_CLEAN];

file->enabled_ns[V3D_CACHE_CLEAN] += runtime;
v3d->queue[V3D_CACHE_CLEAN].enabled_ns += runtime;

file->jobs_sent[V3D_CACHE_CLEAN]++;
v3d->queue[V3D_CACHE_CLEAN].jobs_sent++;

file->start_ns[V3D_CACHE_CLEAN] = 0;
v3d->queue[V3D_CACHE_CLEAN].start_ns = 0;
v3d_job_update_stats(job, V3D_CACHE_CLEAN);

return NULL;
}
Expand Down

0 comments on commit 52ce977

Please sign in to comment.