From: Rob Clark <robdclark@xxxxxxxxxxxx> Minimize interactive latency by boosting frequency when userspace is waiting on the GPU to finish. Signed-off-by: Rob Clark <robdclark@xxxxxxxxxxxx> --- I did contemplate also boosting on dma_fence_wait(), but (a) that would require some extra plumbing thru gpu-sched, (b) that only captures a sub-set of wait-on-dma-fence patterns, and (c) waiting on a dma-fence doesn't always imply urgency (for ex, virglrenderer poll()ing on a dma- fence to know when to send a fence irq to VM guest). But the driver WAIT_FENCE and CPU_PREP ioctls map to things like glFinish() where it is pretty clear that there is something wishing the GPU would finish sooner. drivers/gpu/drm/msm/msm_drv.c | 7 +++++-- drivers/gpu/drm/msm/msm_gem.c | 6 ++++++ drivers/gpu/drm/msm/msm_gpu_devfreq.c | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c3b77b44b2aa..017a512982a2 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -894,7 +894,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, } static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, - ktime_t timeout) + ktime_t timeout, struct msm_gpu *gpu) { struct dma_fence *fence; int ret; @@ -924,6 +924,9 @@ static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id, if (!fence) return 0; + if (!dma_fence_is_signaled(fence)) + msm_devfreq_boost(gpu, 2); + ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout)); if (ret == 0) { ret = -ETIMEDOUT; @@ -956,7 +959,7 @@ static int msm_ioctl_wait_fence(struct drm_device *dev, void *data, if (!queue) return -ENOENT; - ret = wait_fence(queue, args->fence, to_ktime(args->timeout)); + ret = wait_fence(queue, args->fence, to_ktime(args->timeout), priv->gpu); msm_submitqueue_put(queue); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 1dee0d18abbb..fbda0e3a94f8 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -846,6 +846,12 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout) op & MSM_PREP_NOSYNC ? 0 : timeout_to_jiffies(timeout); long ret; + if (!dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(write))) { + struct msm_drm_private *priv = obj->dev->dev_private; + + msm_devfreq_boost(priv->gpu, 2); + } + ret = dma_resv_wait_timeout(obj->resv, dma_resv_usage_rw(write), true, remain); if (ret == 0) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 85c443a37e4e..025940eb08d1 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -305,7 +305,7 @@ void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor) struct msm_gpu_devfreq *df = &gpu->devfreq; uint64_t freq; - if (!has_devfreq(gpu)) + if (!gpu || !has_devfreq(gpu)) return; freq = get_freq(gpu); -- 2.38.1