drm/sched: Do not overaccount job runtime
Subsystems (3)
PATCH 1/1 drm/sched: Do not overaccount job runtime
Currently the starting timestamp of the next job on the timeline is adjusted to the end of a preceding job. This works if the next job has been submitted while the preceding job was still executing, but not if it was submitted in the window between it finishing and free job work running the timestamp adjustment.
This can happen because the run job and free job work items share the same ordered workqueue and run job can easily submit the next job before the free job gets a chance to run. This over accounting window is present especially with single credit schedulers, but not limited too.
Fix it by only adjusting the starting timestamp if it is not already after the finish time of the preceding job.
While at it move the logic to a helper to keep indendation at bay.
--- drivers/gpu/drm/scheduler/sched_main.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
drivers/gpu/drm/scheduler/sched_main.c +19 -5
@@ -898,6 +898,24 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)return IS_ERR (entity) ?NULL : entity; } +static void +adjust_next_job_start (struct drm_sched_job *job,struct drm_sched_job *next) +{ +struct dma_fence *next_scheduled = &next->s_fence->scheduled; +ktime_t ts; + +if (!test_bit (DMA_FENCE_FLAG_TIMESTAMP_BIT , &next_scheduled->flags)) +return ; + +/* +* If the next job has been submitted while the previous one was still +* running adjust it's starting timestamp to avoid accounting overlap. +*/ + ts =dma_fence_timestamp (&job->s_fence->finished); +if (ktime_after (ts, next_scheduled->timestamp)) + next_scheduled->timestamp = ts; +} +/** * drm_sched_get_finished_job - fetch the next finished job to be destroyed *
@@ -929,11 +947,7 @@ drm_sched_get_finished_job(struct drm_gpu_scheduler *sched) typeof(*next), list);if (next) {/* make the scheduled timestamp more accurate */ -if (test_bit (DMA_FENCE_FLAG_TIMESTAMP_BIT , - &next->s_fence->scheduled.flags)) - next->s_fence->scheduled.timestamp = -dma_fence_timestamp (&job->s_fence->finished); - +adjust_next_job_start (job, next);/* start TO timer for next job */ drm_sched_start_timeout (sched); }
Signature · 1 line
2.56.0