Only allow each client to perform one RPS boost in each period of GPU activity. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 8 +++++--- drivers/gpu/drm/i915/i915_gem.c | 18 ++++++------------ drivers/gpu/drm/i915/i915_gem_request.c | 17 ++--------------- drivers/gpu/drm/i915/intel_drv.h | 3 ++- drivers/gpu/drm/i915/intel_pm.c | 29 ++++++++++++++++++++++------- 5 files changed, 37 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index da33964ce711..cefe67fb3949 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -991,6 +991,7 @@ struct intel_gen6_power_mgmt { bool enabled; struct delayed_work delayed_resume_work; + struct list_head clients; bool is_bdw_sw_turbo; /* Switch of BDW software turbo */ struct intel_rps_bdw_turbo sw_turbo; /* Calculate RP interrupt timing */ @@ -1880,12 +1881,13 @@ struct drm_i915_file_private { struct { spinlock_t lock; struct list_head request_list; - struct delayed_work idle_work; } mm; struct idr context_idr; - atomic_t rps_wait_boost; - struct intel_engine_cs *bsd_engine; + struct list_head rps_boost; + struct intel_engine_cs *bsd_engine; + + unsigned rps_boosts; }; /* diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4d46170f4b74..abbe2c6196cd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4650,8 +4650,6 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; - cancel_delayed_work_sync(&file_priv->mm.idle_work); - /* Clean up our request list when the client is going away, so that * later retire_requests won't dereference our soon-to-be-gone * file_priv. @@ -4667,15 +4665,12 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file) rq->file_priv = NULL; } spin_unlock(&file_priv->mm.lock); -} - -static void -i915_gem_file_idle_work_handler(struct work_struct *work) -{ - struct drm_i915_file_private *file_priv = - container_of(work, typeof(*file_priv), mm.idle_work.work); - atomic_set(&file_priv->rps_wait_boost, false); + if (!list_empty(&file_priv->rps_boost)) { + mutex_lock(&to_i915(dev)->rps.hw_lock); + list_del(&file_priv->rps_boost); + mutex_unlock(&to_i915(dev)->rps.hw_lock); + } } int i915_gem_open(struct drm_device *dev, struct drm_file *file) @@ -4692,11 +4687,10 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file) file->driver_priv = file_priv; file_priv->dev_priv = dev->dev_private; file_priv->file = file; + INIT_LIST_HEAD(&file_priv->rps_boost); spin_lock_init(&file_priv->mm.lock); INIT_LIST_HEAD(&file_priv->mm.request_list); - INIT_DELAYED_WORK(&file_priv->mm.idle_work, - i915_gem_file_idle_work_handler); ret = i915_gem_context_open(dev, file); if (ret) diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c index 49f93faa0db0..ca777f6c35d7 100644 --- a/drivers/gpu/drm/i915/i915_gem_request.c +++ b/drivers/gpu/drm/i915/i915_gem_request.c @@ -408,14 +408,6 @@ static bool missed_irq(struct i915_gem_request *rq) return test_bit(rq->engine->id, &rq->i915->gpu_error.missed_irq_rings); } -static bool can_wait_boost(struct drm_i915_file_private *file_priv) -{ - if (file_priv == NULL) - return true; - - return !atomic_xchg(&file_priv->rps_wait_boost, true); -} - bool __i915_request_complete__wa(struct i915_gem_request *rq) { struct drm_i915_private *dev_priv = rq->i915; @@ -475,13 +467,8 @@ int __i915_request_wait(struct i915_gem_request *rq, timeout_expire = timeout_ns ? jiffies + nsecs_to_jiffies((u64)*timeout_ns) : 0; - if (INTEL_INFO(rq->i915)->gen >= 6 && rq->engine->id == RCS && can_wait_boost(file_priv)) { - gen6_rps_boost(rq->i915); - if (file_priv) - mod_delayed_work(rq->i915->wq, - &file_priv->mm.idle_work, - msecs_to_jiffies(100)); - } + if (rq->engine->id == RCS && INTEL_INFO(rq->i915)->gen >= 6) + gen6_rps_boost(rq->i915, file_priv); if (!irq_test_in_progress && WARN_ON(!rq->engine->irq_get(rq->engine))) return -ENODEV; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bbd59dd7be1b..36bf92b026a7 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1076,7 +1076,8 @@ void intel_reset_gt_powersave(struct drm_device *dev); void ironlake_teardown_rc6(struct drm_device *dev); void gen6_update_ring_freq(struct drm_device *dev); void gen6_rps_idle(struct drm_i915_private *dev_priv); -void gen6_rps_boost(struct drm_i915_private *dev_priv); +void gen6_rps_boost(struct drm_i915_private *dev_priv, + struct drm_i915_file_private *file_priv); void intel_queue_rps_boost_for_request(struct drm_device *dev, struct i915_gem_request *rq); void intel_aux_display_runtime_get(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a560eb109160..c8ea3ff6e062 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3459,23 +3459,37 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) dev_priv->rps.last_adj = 0; } + + while (!list_empty(&dev_priv->rps.clients)) + list_del_init(dev_priv->rps.clients.next); mutex_unlock(&dev_priv->rps.hw_lock); } -void gen6_rps_boost(struct drm_i915_private *dev_priv) +void gen6_rps_boost(struct drm_i915_private *dev_priv, + struct drm_i915_file_private *file_priv) { struct drm_device *dev = dev_priv->dev; + u32 val; mutex_lock(&dev_priv->rps.hw_lock); - if (dev_priv->rps.enabled) { + val = dev_priv->rps.max_freq_softlimit; + if (dev_priv->rps.enabled && + dev_priv->rps.cur_freq != val && + (file_priv == NULL || list_empty(&file_priv->rps_boost))) { if (IS_VALLEYVIEW(dev)) - valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); - else if (!dev_priv->rps.is_bdw_sw_turbo - || atomic_read(&dev_priv->rps.sw_turbo.flip_received)){ - gen6_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); + valleyview_set_rps(dev_priv->dev, val); + else if (!dev_priv->rps.is_bdw_sw_turbo || + atomic_read(&dev_priv->rps.sw_turbo.flip_received)) { + gen6_set_rps(dev_priv->dev, val); } dev_priv->rps.last_adj = 0; + + if (file_priv != NULL) { + file_priv->rps_boosts++; + list_move(&file_priv->rps_boost, + &dev_priv->rps.clients); + } } mutex_unlock(&dev_priv->rps.hw_lock); } @@ -7578,7 +7592,7 @@ static void __intel_rps_boost_work(struct work_struct *work) struct request_boost *boost = container_of(work, struct request_boost, work); if (!i915_request_complete(boost->rq)) - gen6_rps_boost(boost->rq->i915); + gen6_rps_boost(boost->rq->i915, NULL); i915_request_put__unlocked(boost->rq); kfree(boost); @@ -7610,6 +7624,7 @@ void intel_pm_setup(struct drm_device *dev) INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, intel_gen6_powersave_work); + INIT_LIST_HEAD(&dev_priv->rps.clients); dev_priv->pm.suspended = false; dev_priv->pm._irqs_disabled = false; -- 2.1.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx