diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-04-27 13:41:24 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-05-21 22:50:05 +0200 |
commit | e61b995841e6d165b77209c2bdf9c96ae0c16b89 (patch) | |
tree | e6d3c6b81bcd972e0958757742be1a7bc7f0f3fb /drivers/gpu/drm/i915 | |
parent | f5a4c67d52e42ad4e76c27287fb7e4a06e11e3fc (diff) |
drm/i915: Free RPS boosts for all laggards
If the client stalls on a congested request, chosen to be 20ms old to
match throttling, allow the client a free RPS boost.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
[danvet: s/rq/req/]
[danvet: s/0/NULL/ reported by 0-day build]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 20 |
3 files changed, 19 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 289178b7e684..50e49a3d7e51 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1245,7 +1245,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, jiffies + nsecs_to_jiffies_timeout((u64)*timeout) : 0; if (INTEL_INFO(dev_priv)->gen >= 6) - gen6_rps_boost(dev_priv, rps); + gen6_rps_boost(dev_priv, rps, req->emitted_jiffies); /* Record current time in case interrupted by signal, or wedged */ trace_i915_gem_request_wait_begin(req); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6968e7483863..e94cb6e16456 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1365,7 +1365,8 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv); void gen6_rps_reset_ei(struct drm_i915_private *dev_priv); void gen6_rps_idle(struct drm_i915_private *dev_priv); void gen6_rps_boost(struct drm_i915_private *dev_priv, - struct intel_rps_client *rps); + struct intel_rps_client *rps, + unsigned long submitted); void intel_queue_rps_boost_for_request(struct drm_device *dev, struct drm_i915_gem_request *req); void ilk_wm_get_hw_state(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b676fe81c563..6414b27692d4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4150,10 +4150,17 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) } void gen6_rps_boost(struct drm_i915_private *dev_priv, - struct intel_rps_client *rps) + struct intel_rps_client *rps, + unsigned long submitted) { u32 val; + /* Force a RPS boost (and don't count it against the client) if + * the GPU is severely congested. + */ + if (rps && time_after(jiffies, submitted + msecs_to_jiffies(20))) + rps = NULL; + mutex_lock(&dev_priv->rps.hw_lock); val = dev_priv->rps.max_freq_softlimit; if (dev_priv->rps.enabled && @@ -6848,11 +6855,13 @@ struct request_boost { static void __intel_rps_boost_work(struct work_struct *work) { struct request_boost *boost = container_of(work, struct request_boost, work); + struct drm_i915_gem_request *req = boost->req; - if (!i915_gem_request_completed(boost->req, true)) - gen6_rps_boost(to_i915(boost->req->ring->dev), NULL); + if (!i915_gem_request_completed(req, true)) + gen6_rps_boost(to_i915(req->ring->dev), NULL, + req->emitted_jiffies); - i915_gem_request_unreference__unlocked(boost->req); + i915_gem_request_unreference__unlocked(req); kfree(boost); } @@ -6864,6 +6873,9 @@ void intel_queue_rps_boost_for_request(struct drm_device *dev, if (req == NULL || INTEL_INFO(dev)->gen < 6) return; + if (i915_gem_request_completed(req, true)) + return; + boost = kmalloc(sizeof(*boost), GFP_ATOMIC); if (boost == NULL) return; |