Skip to content

Commit

Permalink
drm/i915: Restore GT performance in headless mode with DMC loaded
Browse files Browse the repository at this point in the history
It seems that the DMC likes to transition between the DC states a lot when
there are no connected displays (no active power domains) during command
submission.

This activity on DC states has a negative impact on the performance of the
chip with huge latencies observed in the interrupt handlers and elsewhere.
Simple tests like igt/gem_latency -n 0 are slowed down by a factor of
eight.

Work around it by introducing a new power domain named,
POWER_DOMAIN_GT_IRQ, associtated with the "DC off" power well, which is
held for the duration of command submission activity.

CNL has the same problem which will be addressed as a follow-up. Doing
that requires a fix for a DC6 context corruption problem in the CNL DMC
firmware which is yet to be released.

v2:
 * Add commit text as comment in i915_gem_mark_busy. (Chris Wilson)
 * Protect macro body with braces. (Jani Nikula)

v3:
 * Add dedicated power domain for clarity. (Chris, Imre)
 * Commit message and comment text updates.
 * Apply to all big-core GEN9 parts apart for Skylake which is pending DMC
   firmware release.

v4:
 * Power domain should be inner to device runtime pm. (Chris)
 * Simplify NEEDS_CSR_GT_PERF_WA macro. (Chris)
 * Handle async DMC loading by moving the GT_IRQ power domain logic into
   intel_runtime_pm. (Daniel, Chris)
 * Include small core GEN9 as well. (Imre)

v5
 * Special handling for async DMC load is not needed since on failure the
   power domain reference is kept permanently taken. (Imre)

v6:
 * Drop the NEEDS_CSR_GT_PERF_WA macro since all firmwares have now been
   deployed. (Imre, Chris)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100572
Testcase: igt/gem_exec_nop/headless
Cc: Imre Deak <imre.deak@intel.com>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk> (v2)
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Dmitry Rogozhkin <dmitry.v.rogozhkin@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> (v5)
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
[Imre: Add note about applying the WA on CNL as a follow-up]
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171205132854.26380-1-tvrtko.ursulin@linux.intel.com
  • Loading branch information
Tvrtko Ursulin authored and Imre Deak committed Dec 8, 2017
1 parent 2fc7a06 commit b687637
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_D,
POWER_DOMAIN_GMBUS,
POWER_DOMAIN_MODESET,
POWER_DOMAIN_GT_IRQ,
POWER_DOMAIN_INIT,

POWER_DOMAIN_NUM,
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3386,6 +3386,9 @@ i915_gem_idle_work_handler(struct work_struct *work)

if (INTEL_GEN(dev_priv) >= 6)
gen6_rps_idle(dev_priv);

intel_display_power_put(dev_priv, POWER_DOMAIN_GT_IRQ);

intel_runtime_pm_put(dev_priv);
out_unlock:
mutex_unlock(&dev_priv->drm.struct_mutex);
Expand Down
14 changes: 14 additions & 0 deletions drivers/gpu/drm/i915/i915_gem_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,20 @@ static void mark_busy(struct drm_i915_private *i915)
GEM_BUG_ON(!i915->gt.active_requests);

intel_runtime_pm_get_noresume(i915);

/*
* It seems that the DMC likes to transition between the DC states a lot
* when there are no connected displays (no active power domains) during
* command submission.
*
* This activity has negative impact on the performance of the chip with
* huge latencies observed in the interrupt handler and elsewhere.
*
* Work around it by grabbing a GT IRQ power domain whilst there is any
* GT activity, preventing any DC state transitions.
*/
intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ);

i915->gt.awake = true;

intel_enable_gt_powersave(i915);
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/intel_runtime_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
return "INIT";
case POWER_DOMAIN_MODESET:
return "MODESET";
case POWER_DOMAIN_GT_IRQ:
return "GT_IRQ";
default:
MISSING_CASE(domain);
return "?";
Expand Down Expand Up @@ -1705,6 +1707,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT_ULL(POWER_DOMAIN_INIT))
#define SKL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
BIT_ULL(POWER_DOMAIN_GT_IRQ) | \
BIT_ULL(POWER_DOMAIN_MODESET) | \
BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_INIT))
Expand All @@ -1727,6 +1730,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT_ULL(POWER_DOMAIN_INIT))
#define BXT_DISPLAY_DC_OFF_POWER_DOMAINS ( \
BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
BIT_ULL(POWER_DOMAIN_GT_IRQ) | \
BIT_ULL(POWER_DOMAIN_MODESET) | \
BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_INIT))
Expand Down Expand Up @@ -1785,6 +1789,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT_ULL(POWER_DOMAIN_INIT))
#define GLK_DISPLAY_DC_OFF_POWER_DOMAINS ( \
GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
BIT_ULL(POWER_DOMAIN_GT_IRQ) | \
BIT_ULL(POWER_DOMAIN_MODESET) | \
BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_INIT))
Expand Down

0 comments on commit b687637

Please sign in to comment.