All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jackie Li <yaodong.li@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [RFC] drm/i915: cpufreq based dynamic ring freqency table on Gen9
Date: Tue, 30 Jan 2018 10:44:46 -0800	[thread overview]
Message-ID: <1517337886-6164-1-git-send-email-yaodong.li@intel.com> (raw)
In-Reply-To: <6d9d0e76-1899-dac0-0c95-5724d8d09ad3@intel.com>

A known issue that ring frequency transition would lead to
a full system stall had impacted the media performance when
the GT frequency is lower than IA freqency and there's heavy
GT workload while having low IA workload. In this case, the
ring frequency will be toggled between GT and IA frequency.
The solution is to keep the ring frequency higher than or
equal to current IA frequency so that we can avoid the toggling
between different frequencies issue.

This patch monitors the cpufreq frequency notifications (freqency
transition notification when governors are used, or new frequency
policy when bypassing the governors such as the active mode of
intel_pstate) and updates the ring frequency table by calculating
the ring frequency for each possible gpu frequency with a new
formula ring_freq = max(current IA freq, 2 * gpu_freq). with this
we can guarantee that the ring frequency would depend on IA freq
when the 2x gpu freq is lower then the active IA freq, and it would
depend on 2x gpu freq once the 2x gpu freq is higher than current
IA freq.

Potential issues with this solution:
0) currently, this patch is now only monitoring the frequency change
   of CPU 0. it would fail if another logic CPU was using a higher
   frequency.
1) the latency of the ring freq table update was not considered.
   Need more understanding to the cost of each ring freq table update.
2) Not sure the impact for low GT workload while the ring frequency
   is still set to higher or equal to IA frequency.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Dmitry Rogozhkin <dmitry.v.rogozhkin@intel.com>
Signed-off-by: Jackie Li <yaodong.li@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |   4 ++
 drivers/gpu/drm/i915/intel_pm.c | 106 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 107 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a689396..39311cd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2044,6 +2044,10 @@ struct drm_i915_private {
 	/* gen6+ GT PM state */
 	struct intel_gen6_power_mgmt gt_pm;
 
+	/* cpufreq notifiers*/
+	struct notifier_block cpufreq_transition;
+	struct notifier_block cpufreq_policy;
+
 	/* ilk-only ips/rps state. Everything in here is protected by the global
 	 * mchdev_lock in intel_pm.c */
 	struct intel_ilk_power_mgmt ips;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1db79a8..6a7e439 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6849,7 +6849,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 	/* convert DDR frequency from units of 266.6MHz to bandwidth */
 	min_ring_freq = mult_frac(min_ring_freq, 8, 3);
 
-	if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
+	if (IS_CANNONLAKE(dev_priv)) {
 		/* Convert GT frequency to 50 HZ units */
 		min_gpu_freq = rps->min_freq / GEN9_FREQ_SCALER;
 		max_gpu_freq = rps->max_freq / GEN9_FREQ_SCALER;
@@ -6867,7 +6867,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 		int diff = max_gpu_freq - gpu_freq;
 		unsigned int ia_freq = 0, ring_freq = 0;
 
-		if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
+		if (IS_CANNONLAKE(dev_priv)) {
 			/*
 			 * ring_freq = 2 * GT. ring_freq is in 100MHz units
 			 * No floor required for ring frequency on SKL.
@@ -8024,6 +8024,103 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 	mutex_unlock(&dev_priv->pcu_lock);
 }
 
+static void gen9_update_ring_freq(struct drm_i915_private *dev_priv,
+				  unsigned int cpu_freq_mhz)
+{
+	struct intel_rps *rps = &dev_priv->gt_pm.rps;
+	unsigned int max_gpu_freq, min_gpu_freq;
+	unsigned int gpu_freq, ring_freq;
+	unsigned int cpu_freq_50mhz = cpu_freq_mhz / 50;
+
+	GEM_BUG_ON(!IS_GEN9(dev_priv));
+
+	mutex_lock(&dev_priv->pcu_lock);
+
+	if (IS_GEN9_BC(dev_priv)) {
+		/* Convert GT frequency to 50MHz units */
+		min_gpu_freq = rps->min_freq / GEN9_FREQ_SCALER;
+		max_gpu_freq = rps->max_freq / GEN9_FREQ_SCALER;
+	} else {
+		min_gpu_freq = rps->min_freq;
+		max_gpu_freq = rps->max_freq;
+	}
+
+	DRM_INFO("%s: gpu freq in 50MHz unit (%d - %d), (%d - %d),"
+		 "cpu freq in 50MHz unit %d\n",
+		 __func__,
+		 min_gpu_freq, max_gpu_freq,
+		 min_gpu_freq * 50,
+		 max_gpu_freq * 50,
+		 cpu_freq_50mhz);
+
+	for (gpu_freq = max_gpu_freq; gpu_freq >= min_gpu_freq; gpu_freq--) {
+		/* Ring freq is 100MHz unit */
+		ring_freq = max(cpu_freq_50mhz / 2, gpu_freq);
+
+		sandybridge_pcode_write(
+			dev_priv,
+			GEN6_PCODE_WRITE_MIN_FREQ_TABLE,
+			ring_freq << GEN6_PCODE_FREQ_RING_RATIO_SHIFT |
+			gpu_freq);
+	}
+
+	mutex_unlock(&dev_priv->pcu_lock);
+}
+
+static int cpufreq_transition_cb(struct notifier_block *nb, unsigned long val,
+				 void *data)
+{
+	struct cpufreq_freqs *freq = data;
+	struct drm_i915_private *i915 = container_of(nb,
+						     struct drm_i915_private,
+						     cpufreq_transition);
+
+	if (val != CPUFREQ_POSTCHANGE)
+		return 0;
+
+	if (freq->cpu != 0)
+		return 0;
+
+	if (freq->new == freq->old)
+		return 0;
+
+	gen9_update_ring_freq(i915, freq->new / 1000);
+
+	return 0;
+}
+
+static int cpufreq_policy_cb(struct notifier_block *nb, unsigned long val,
+			     void *data)
+{
+	struct cpufreq_policy *policy = data;
+	struct drm_i915_private *i915 = container_of(nb,
+						     struct drm_i915_private,
+						     cpufreq_policy);
+
+	if (val != CPUFREQ_NOTIFY)
+		return 0;
+
+	if (policy->cpu != 0)
+		return 0;
+
+	gen9_update_ring_freq(i915, policy->max / 1000);
+
+	return 0;
+}
+
+
+static inline
+void intel_register_cpufreq_notifiers(struct drm_i915_private *i915)
+{
+	i915->cpufreq_transition.notifier_call = cpufreq_transition_cb;
+	i915->cpufreq_policy.notifier_call = cpufreq_policy_cb;
+
+	cpufreq_register_notifier(&i915->cpufreq_transition,
+				  CPUFREQ_TRANSITION_NOTIFIER);
+	cpufreq_register_notifier(&i915->cpufreq_policy,
+				  CPUFREQ_POLICY_NOTIFIER);
+}
+
 static inline void intel_enable_llc_pstate(struct drm_i915_private *i915)
 {
 	lockdep_assert_held(&i915->pcu_lock);
@@ -8031,7 +8128,10 @@ static inline void intel_enable_llc_pstate(struct drm_i915_private *i915)
 	if (i915->gt_pm.llc_pstate.enabled)
 		return;
 
-	gen6_update_ring_freq(i915);
+	if (IS_GEN9(i915))
+		intel_register_cpufreq_notifiers(i915);
+	else
+		gen6_update_ring_freq(i915);
 
 	i915->gt_pm.llc_pstate.enabled = true;
 }
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2018-01-30 18:46 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-18 21:22 [RFC] drm/i915: Add a new modparam for customized ring multiplier Jackie Li
2017-12-18 21:45 ` ✓ Fi.CI.BAT: success for " Patchwork
2017-12-18 21:47 ` [RFC] " Chris Wilson
2017-12-19  1:10   ` Yaodong Li
2017-12-26 14:35   ` Chris Wilson
2017-12-26 16:39     ` Rogozhkin, Dmitry V
2017-12-26 16:58       ` Chris Wilson
2017-12-26 17:39         ` Rogozhkin, Dmitry V
2017-12-27 17:43           ` Rogozhkin, Dmitry V
2018-01-03 18:21           ` Yaodong Li
2018-01-04  6:10             ` Sagar Arun Kamble
2018-01-04 21:52               ` Yaodong Li
2018-01-05 10:15                 ` Sagar Arun Kamble
2018-01-06  0:23                   ` Yaodong Li
2018-01-08  9:11                     ` Sagar Arun Kamble
2018-01-30 18:44                     ` Jackie Li [this message]
2017-12-18 22:36 ` ✗ Fi.CI.IGT: failure for " Patchwork
2018-01-30 20:23 ` ✗ Fi.CI.BAT: failure for drm/i915: Add a new modparam for customized ring multiplier (rev2) Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1517337886-6164-1-git-send-email-yaodong.li@intel.com \
    --to=yaodong.li@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.