Only allow each client to perform one RPS boost in each period of GPU
activity.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to