diff options
| author | Matthew Brost <matthew.brost@intel.com> | 2025-12-12 21:28:42 +0300 |
|---|---|---|
| committer | Matthew Brost <matthew.brost@intel.com> | 2025-12-16 00:53:32 +0300 |
| commit | ca415c4d4c17ad676a2c8981e1fcc432221dce79 (patch) | |
| tree | 914861aaba696b0908622bd8961e0d4ecc5807e0 | |
| parent | 33a5abd9a68394aa67f9618b20eee65ee8702ff4 (diff) | |
| download | linux-ca415c4d4c17ad676a2c8981e1fcc432221dce79.tar.xz | |
drm/xe: Use usleep_range for accurate long-running workload timeslicing
msleep is not very accurate in terms of how long it actually sleeps,
whereas usleep_range is precise. Replace the timeslice sleep for
long-running workloads with the more accurate usleep_range to avoid
jitter if the sleep period is less than 20ms.
Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Cc: stable@vger.kernel.org
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/20251212182847.1683222-3-matthew.brost@intel.com
| -rw-r--r-- | drivers/gpu/drm/xe/xe_guc_submit.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 21a8bd2ec672..18cac5594d6a 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -990,6 +990,24 @@ static u32 wq_space_until_wrap(struct xe_exec_queue *q) return (WQ_SIZE - q->guc->wqi_tail); } +static inline void relaxed_ms_sleep(unsigned int delay_ms) +{ + unsigned long min_us, max_us; + + if (!delay_ms) + return; + + if (delay_ms > 20) { + msleep(delay_ms); + return; + } + + min_us = mul_u32_u32(delay_ms, 1000); + max_us = min_us + 500; + + usleep_range(min_us, max_us); +} + static int wq_wait_for_space(struct xe_exec_queue *q, u32 wqi_size) { struct xe_guc *guc = exec_queue_to_guc(q); @@ -1903,7 +1921,7 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg) since_resume_ms; if (wait_ms > 0 && q->guc->resume_time) - msleep(wait_ms); + relaxed_ms_sleep(wait_ms); set_exec_queue_suspended(q); disable_scheduling(q, false); |
