[Intel-gfx] [PATCH 04/10] drm/i915: Deminish contribution of wait-boosting from clients

Chris Wilson chris at chris-wilson.co.uk
Tue Sep 2 15:57:39 CEST 2014


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

Signed-off-by: Chris Wilson <chris at 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




More information about the Intel-gfx mailing list