[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