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> From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Wed, 4 Jul 2018 08:45:48 +0100 X-Patchwork-Id: 10521163
Subject: [PATCH] drm/i915: Interactive RPS mode 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 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 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, just in case a dramatic change in system load requires urgent uplocking,
faster than we can provide in a few evaluation intervals.) faster than we can provide in a few evaluation intervals.)
References: https://bugs.freedesktop.org/show_bug.cgi?id=107111 v2: Reduce rps_set_interactive to a boolean parameter to avoid the
References: e9af4ea2b9e7 ("drm/i915: Avoid waitboosting on the active request") 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> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com> Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
--- ---
drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 1 +
drivers/gpu/drm/i915/i915_drv.h | 6 +- drivers/gpu/drm/i915/i915_drv.h | 4 ++
drivers/gpu/drm/i915/intel_display.c | 20 +++++++ drivers/gpu/drm/i915/intel_display.c | 20 ++++++
drivers/gpu/drm/i915/intel_drv.h | 2 + drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_pm.c | 87 ++++++++++++++++++---------- drivers/gpu/drm/i915/intel_pm.c | 91 +++++++++++++++++++---------
5 files changed, 86 insertions(+), 30 deletions(-) 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 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 --- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/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) @@ -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, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
seq_printf(m, "Boosts outstanding? %d\n", seq_printf(m, "Boosts outstanding? %d\n",
atomic_read(&rps->num_waiters)); 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", seq_printf(m, "Frequency requested %d\n",
intel_gpu_freq(dev_priv, rps->cur_freq)); intel_gpu_freq(dev_priv, rps->cur_freq));
seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n", 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 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 --- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -783,7 +783,9 @@ struct intel_rps { @@ -784,6 +784,8 @@ struct intel_rps {
u8 down_threshold; /* Current %busy required to downclock */
int last_adj; int last_adj;
- enum { LOW_POWER, BETWEEN, HIGH_POWER } power; enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
+ enum { LOW_POWER, BETWEEN, HIGH_POWER, AUTO_POWER } power; + unsigned int interactive;
+ unsigned int power_override;
+ struct mutex power_lock; + struct mutex power_lock;
bool enabled; bool enabled;
@ -81,13 +92,13 @@ index 09ab12458244..3f9ae1095b98 100644
extern bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val); 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 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 int intel_set_rps(struct drm_i915_private *dev_priv, u8 val);
+extern void intel_rps_set_power(struct drm_i915_private *dev_priv, +extern void intel_rps_set_interactive(struct drm_i915_private *dev_priv,
+ int new_power); + bool state);
extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
bool enable); bool enable);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c 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 --- a/drivers/gpu/drm/i915/intel_display.c
+++ b/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, @@ -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 + * that are not quite steady state without resorting to forcing
+ * maximum clocks following a vblank miss (see do_rps_boost()). + * maximum clocks following a vblank miss (see do_rps_boost()).
+ */ + */
+ if (!intel_state->rps_override) { + if (!intel_state->rps_interactive) {
+ intel_rps_set_power(dev_priv, HIGH_POWER); + intel_rps_set_interactive(dev_priv, true);
+ intel_state->rps_override = true; + intel_state->rps_interactive = true;
+ } + }
+ +
return 0; return 0;
@ -118,29 +129,29 @@ index 8f3199b06d1f..acedd9b2d54a 100644
+ to_intel_atomic_state(old_state->state); + to_intel_atomic_state(old_state->state);
struct drm_i915_private *dev_priv = to_i915(plane->dev); struct drm_i915_private *dev_priv = to_i915(plane->dev);
+ if (intel_state->rps_override) { + if (intel_state->rps_interactive) {
+ intel_rps_set_power(dev_priv, AUTO_POWER); + intel_rps_set_interactive(dev_priv, false);
+ intel_state->rps_override = false; + intel_state->rps_interactive = false;
+ } + }
+ +
/* Should only be called after a successful intel_prepare_plane_fb()! */ /* Should only be called after a successful intel_prepare_plane_fb()! */
mutex_lock(&dev_priv->drm.struct_mutex); mutex_lock(&dev_priv->drm.struct_mutex);
intel_plane_unpin_fb(to_intel_plane_state(old_state)); 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 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 --- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -482,6 +482,8 @@ struct intel_atomic_state { @@ -482,6 +482,8 @@ struct intel_atomic_state {
*/ */
bool skip_intermediate_wm; bool skip_intermediate_wm;
+ bool rps_override; + bool rps_interactive;
+ +
/* Gen9+ only */ /* Gen9+ only */
struct skl_ddb_values wm_results; struct skl_ddb_values wm_results;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c 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 --- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/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) @@ -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) - val > rps->cur_freq)
- new_power = BETWEEN; - new_power = BETWEEN;
- break; - break;
- + lockdep_assert_held(&rps->power_lock);
- case BETWEEN: - case BETWEEN:
- if (val <= rps->efficient_freq && - if (val <= rps->efficient_freq &&
- val < rps->cur_freq) - val < rps->cur_freq)
@ -171,8 +183,7 @@ index 53aaaa3e6886..0245a90d0fe5 100644
- val > rps->cur_freq) - val > rps->cur_freq)
- new_power = HIGH_POWER; - new_power = HIGH_POWER;
- break; - break;
+ lockdep_assert_held(&rps->power_lock); -
- case HIGH_POWER: - case HIGH_POWER:
- if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 && - if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
- val < rps->cur_freq) - val < rps->cur_freq)
@ -187,7 +198,7 @@ index 53aaaa3e6886..0245a90d0fe5 100644
if (new_power == rps->power) if (new_power == rps->power)
return; 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->power = new_power;
rps->up_threshold = threshold_up; rps->up_threshold = threshold_up;
rps->down_threshold = threshold_down; rps->down_threshold = threshold_down;
@ -200,7 +211,6 @@ index 53aaaa3e6886..0245a90d0fe5 100644
+ +
+ new_power = rps->power; + new_power = rps->power;
+ switch (rps->power) { + switch (rps->power) {
+ case AUTO_POWER:
+ case LOW_POWER: + case LOW_POWER:
+ if (val > rps->efficient_freq + 1 && + if (val > rps->efficient_freq + 1 &&
+ val > rps->cur_freq) + val > rps->cur_freq)
@ -229,22 +239,27 @@ index 53aaaa3e6886..0245a90d0fe5 100644
+ new_power = HIGH_POWER; + new_power = HIGH_POWER;
+ +
+ mutex_lock(&rps->power_lock); + mutex_lock(&rps->power_lock);
+ if (!rps->power_override) + if (rps->interactive)
+ rps_set_power(dev_priv, new_power); + new_power = HIGH_POWER;
+ rps_set_power(dev_priv, new_power);
+ mutex_unlock(&rps->power_lock); + mutex_unlock(&rps->power_lock);
rps->last_adj = 0; 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; + struct intel_rps *rps = &dev_priv->gt_pm.rps;
+ +
+ if (INTEL_GEN(dev_priv) < 6)
+ return;
+
+ mutex_lock(&rps->power_lock); + mutex_lock(&rps->power_lock);
+ if (power != AUTO_POWER) { + if (state) {
+ rps->power_override++; + if (!rps->interactive++ && READ_ONCE(dev_priv->gt.awake))
+ rps_set_power(dev_priv, power); + rps_set_power(dev_priv, HIGH_POWER);
+ } else { + } else {
+ rps->power_override--; + GEM_BUG_ON(!rps->interactive);
+ rps->interactive--;
+ } + }
+ mutex_unlock(&rps->power_lock); + 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) static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps; 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) void intel_pm_setup(struct drm_i915_private *dev_priv)
{ {
mutex_init(&dev_priv->pcu_lock); mutex_init(&dev_priv->pcu_lock);
@ -260,6 +275,3 @@ index 53aaaa3e6886..0245a90d0fe5 100644
atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0); atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0);
--
2.18.0