diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 173d1e4ad963..b312ac006d24 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3708,7 +3708,29 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) static int wait_for_timeline(struct i915_timeline *tl, unsigned int flags) { - return i915_gem_active_wait(&tl->last_request, flags); + struct i915_request *rq; + long ret; + + rq = i915_gem_active_get_unlocked(&tl->last_request); + if (!rq) + return 0; + + /* + * "Race-to-idle". + * + * Switching to the kernel context is often used a synchronous + * step prior to idling, e.g. in suspend for flushing all + * current operations to memory before sleeping. These we + * want to complete as quickly as possible to avoid prolonged + * stalls, so allow the gpu to boost to maximum clocks. + */ + if (flags & I915_WAIT_FOR_IDLE_BOOST) + gen6_rps_boost(rq, NULL); + + ret = i915_request_wait(rq, flags, MAX_SCHEDULE_TIMEOUT); + i915_request_put(rq); + + return ret < 0 ? ret : 0; } static int wait_for_engines(struct drm_i915_private *i915) @@ -4983,7 +5005,8 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv) ret = i915_gem_wait_for_idle(dev_priv, I915_WAIT_INTERRUPTIBLE | - I915_WAIT_LOCKED); + I915_WAIT_LOCKED | + I915_WAIT_FOR_IDLE_BOOST); if (ret && ret != -EIO) goto err_unlock; |