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;
        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;
        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;
        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;
 
                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;
        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.
 {
        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;
 
        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 */
 {
        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;
 
 
        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);
 {
        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;
 
        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);
 {
        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;
 
                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;
 }
 {
        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;
 }