linux: update RPS waitboosting patch to V4

This commit is contained in:
MilhouseVH 2018-07-15 07:11:08 +01:00
parent baa76a35f5
commit 563d2c2d5e

View File

@ -1,7 +1,13 @@
From 77a8e4fee1ad8cf7ec4a8899f76dfb9303b422f8 Mon Sep 17 00:00:00 2001
From patchwork Thu Jul 12 08:02:24 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v4] drm/i915: Interactive RPS mode
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Wed, 4 Jul 2018 08:45:48 +0100
Subject: [PATCH] drm/i915: Interactive RPS mode
X-Patchwork-Id: 10521163
Message-Id: <20180712080224.29831-1-chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Date: Thu, 12 Jul 2018 09:02:24 +0100
RPS provides a feedback loop where we use the load during the previous
evaluation interval to decide whether to up or down clock the GPU
@ -36,43 +42,48 @@ work back down again. (We still keep the waitboosting mechanism around
just in case a dramatic change in system load requires urgent uplocking,
faster than we can provide in a few evaluation intervals.)
References: https://bugs.freedesktop.org/show_bug.cgi?id=107111
References: e9af4ea2b9e7 ("drm/i915: Avoid waitboosting on the active request")
v2: Reduce rps_set_interactive to a boolean parameter to avoid the
confusion of what if they wanted a new power mode after pinning to a
different mode (which to choose?)
v3: Only reprogram RPS while the GT is awake, it will be set when we
wake the GT, and while off warns about being used outside of rpm.
v4: Fix deferred application of interactive mode
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107111
Fixes: e9af4ea2b9e7 ("drm/i915: Avoid waitboosting on the active request")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 1 +
drivers/gpu/drm/i915/i915_drv.h | 6 +-
drivers/gpu/drm/i915/intel_display.c | 20 +++++++
drivers/gpu/drm/i915/i915_drv.h | 4 ++
drivers/gpu/drm/i915/intel_display.c | 20 ++++++
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_pm.c | 87 ++++++++++++++++++----------
5 files changed, 86 insertions(+), 30 deletions(-)
drivers/gpu/drm/i915/intel_pm.c | 91 +++++++++++++++++++---------
5 files changed, 89 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 544e5e7f011f..7d974cad1cdf 100644
index 099f97ef2303..ac019bb927d0 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2218,6 +2218,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
seq_printf(m, "Boosts outstanding? %d\n",
atomic_read(&rps->num_waiters));
+ seq_printf(m, "Power overrides? %d\n", READ_ONCE(rps->power_override));
+ seq_printf(m, "Interactive? %d\n", READ_ONCE(rps->interactive));
seq_printf(m, "Frequency requested %d\n",
intel_gpu_freq(dev_priv, rps->cur_freq));
seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 09ab12458244..3f9ae1095b98 100644
index 01dd29837233..f02fbeee553f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -783,7 +783,9 @@ struct intel_rps {
u8 down_threshold; /* Current %busy required to downclock */
@@ -784,6 +784,8 @@ struct intel_rps {
int last_adj;
- enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
+ enum { LOW_POWER, BETWEEN, HIGH_POWER, AUTO_POWER } power;
+ unsigned int power_override;
enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
+ unsigned int interactive;
+ struct mutex power_lock;
bool enabled;
@ -81,13 +92,13 @@ index 09ab12458244..3f9ae1095b98 100644
extern bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val);
extern void intel_init_pch_refclk(struct drm_i915_private *dev_priv);
extern int intel_set_rps(struct drm_i915_private *dev_priv, u8 val);
+extern void intel_rps_set_power(struct drm_i915_private *dev_priv,
+ int new_power);
+extern void intel_rps_set_interactive(struct drm_i915_private *dev_priv,
+ bool state);
extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
bool enable);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8f3199b06d1f..acedd9b2d54a 100644
index 7998e70a3174..5809366ff9f0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13104,6 +13104,19 @@ intel_prepare_plane_fb(struct drm_plane *plane,
@ -102,9 +113,9 @@ index 8f3199b06d1f..acedd9b2d54a 100644
+ * that are not quite steady state without resorting to forcing
+ * maximum clocks following a vblank miss (see do_rps_boost()).
+ */
+ if (!intel_state->rps_override) {
+ intel_rps_set_power(dev_priv, HIGH_POWER);
+ intel_state->rps_override = true;
+ if (!intel_state->rps_interactive) {
+ intel_rps_set_interactive(dev_priv, true);
+ intel_state->rps_interactive = true;
+ }
+
return 0;
@ -118,29 +129,29 @@ index 8f3199b06d1f..acedd9b2d54a 100644
+ to_intel_atomic_state(old_state->state);
struct drm_i915_private *dev_priv = to_i915(plane->dev);
+ if (intel_state->rps_override) {
+ intel_rps_set_power(dev_priv, AUTO_POWER);
+ intel_state->rps_override = false;
+ if (intel_state->rps_interactive) {
+ intel_rps_set_interactive(dev_priv, false);
+ intel_state->rps_interactive = false;
+ }
+
/* Should only be called after a successful intel_prepare_plane_fb()! */
mutex_lock(&dev_priv->drm.struct_mutex);
intel_plane_unpin_fb(to_intel_plane_state(old_state));
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 61e715ddd0d5..86685c43e1d2 100644
index 61e715ddd0d5..544812488821 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -482,6 +482,8 @@ struct intel_atomic_state {
*/
bool skip_intermediate_wm;
+ bool rps_override;
+ bool rps_interactive;
+
/* Gen9+ only */
struct skl_ddb_values wm_results;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 53aaaa3e6886..0245a90d0fe5 100644
index 53aaaa3e6886..01475bf3196a 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6264,41 +6264,14 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
@ -162,7 +173,8 @@ index 53aaaa3e6886..0245a90d0fe5 100644
- val > rps->cur_freq)
- new_power = BETWEEN;
- break;
-
+ lockdep_assert_held(&rps->power_lock);
- case BETWEEN:
- if (val <= rps->efficient_freq &&
- val < rps->cur_freq)
@ -171,8 +183,7 @@ index 53aaaa3e6886..0245a90d0fe5 100644
- val > rps->cur_freq)
- new_power = HIGH_POWER;
- break;
+ lockdep_assert_held(&rps->power_lock);
-
- case HIGH_POWER:
- if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
- val < rps->cur_freq)
@ -187,7 +198,7 @@ index 53aaaa3e6886..0245a90d0fe5 100644
if (new_power == rps->power)
return;
@@ -6365,9 +6338,64 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
@@ -6365,9 +6338,68 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
rps->power = new_power;
rps->up_threshold = threshold_up;
rps->down_threshold = threshold_down;
@ -200,7 +211,6 @@ index 53aaaa3e6886..0245a90d0fe5 100644
+
+ new_power = rps->power;
+ switch (rps->power) {
+ case AUTO_POWER:
+ case LOW_POWER:
+ if (val > rps->efficient_freq + 1 &&
+ val > rps->cur_freq)
@ -229,22 +239,27 @@ index 53aaaa3e6886..0245a90d0fe5 100644
+ new_power = HIGH_POWER;
+
+ mutex_lock(&rps->power_lock);
+ if (!rps->power_override)
+ rps_set_power(dev_priv, new_power);
+ if (rps->interactive)
+ new_power = HIGH_POWER;
+ rps_set_power(dev_priv, new_power);
+ mutex_unlock(&rps->power_lock);
rps->last_adj = 0;
}
+void intel_rps_set_power(struct drm_i915_private *dev_priv, int power)
+void intel_rps_set_interactive(struct drm_i915_private *dev_priv, bool state)
+{
+ struct intel_rps *rps = &dev_priv->gt_pm.rps;
+
+ if (INTEL_GEN(dev_priv) < 6)
+ return;
+
+ mutex_lock(&rps->power_lock);
+ if (power != AUTO_POWER) {
+ rps->power_override++;
+ rps_set_power(dev_priv, power);
+ if (state) {
+ if (!rps->interactive++ && READ_ONCE(dev_priv->gt.awake))
+ rps_set_power(dev_priv, HIGH_POWER);
+ } else {
+ rps->power_override--;
+ GEM_BUG_ON(!rps->interactive);
+ rps->interactive--;
+ }
+ mutex_unlock(&rps->power_lock);
+}
@ -252,7 +267,7 @@ index 53aaaa3e6886..0245a90d0fe5 100644
static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
{
struct intel_rps *rps = &dev_priv->gt_pm.rps;
@@ -9604,6 +9632,7 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
@@ -9604,6 +9636,7 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
void intel_pm_setup(struct drm_i915_private *dev_priv)
{
mutex_init(&dev_priv->pcu_lock);
@ -260,6 +275,3 @@ index 53aaaa3e6886..0245a90d0fe5 100644
atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0);
--
2.18.0