[PATCH 2/2] drm/i915: Defer rc6 shutdown to suspend_late
Chris Wilson
chris at chris-wilson.co.uk
Mon Oct 7 10:54:45 UTC 2019
Currently we shutdown rc6 during i915_gem_resume() but this is called
during the preparation phase (i915_drm_prepare) for all suspend paths,
but we only want to shutdown rc6 for S3+. Move the actual shutdown to
i915_gem_suspend_late().
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111909
Fixes: c113236718e8 ("drm/i915: Extract GT render sleep (rc6) management")
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Andi Shyti <andi.shyti at intel.com>
---
drivers/gpu/drm/i915/gem/i915_gem_pm.c | 7 +++----
drivers/gpu/drm/i915/gt/intel_gt_pm.c | 14 +++++++++++---
drivers/gpu/drm/i915/gt/intel_gt_pm.h | 3 ++-
drivers/gpu/drm/i915/gt/intel_rc6.c | 5 +++++
drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 2 +-
5 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 7987b54fb1f5..f09684b96656 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
@@ -97,8 +97,7 @@ void i915_gem_suspend(struct drm_i915_private *i915)
* state. Fortunately, the kernel_context is disposable and we do
* not rely on its state.
*/
- intel_gt_suspend(&i915->gt);
- intel_uc_suspend(&i915->gt.uc);
+ intel_gt_suspend_prepare(&i915->gt);
cancel_delayed_work_sync(&i915->gt.hangcheck.work);
@@ -142,6 +141,8 @@ void i915_gem_suspend_late(struct drm_i915_private *i915)
* machine in an unusable condition.
*/
+ intel_gt_suspend_late(&i915->gt);
+
spin_lock_irqsave(&i915->mm.obj_lock, flags);
for (phase = phases; *phase; phase++) {
LIST_HEAD(keep);
@@ -187,8 +188,6 @@ void i915_gem_resume(struct drm_i915_private *i915)
if (intel_gt_resume(&i915->gt))
goto err_wedged;
- intel_uc_resume(&i915->gt.uc);
-
/* Always reload a context for powersaving. */
if (!i915_gem_load_power_context(i915))
goto err_wedged;
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index b52e2ba3d092..472d3d59b0d3 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -168,7 +168,9 @@ int intel_gt_resume(struct intel_gt *gt)
*/
intel_gt_pm_get(gt);
intel_uncore_forcewake_get(gt->uncore, FORCEWAKE_ALL);
+
intel_rc6_sanitize(>->rc6);
+ intel_uc_resume(>->uc);
for_each_engine(engine, gt->i915, id) {
struct intel_context *ce;
@@ -196,14 +198,18 @@ int intel_gt_resume(struct intel_gt *gt)
}
intel_rc6_enable(>->rc6);
+
intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL);
intel_gt_pm_put(gt);
return err;
}
-static void wait_for_idle(struct intel_gt *gt)
+void intel_gt_suspend_prepare(struct intel_gt *gt)
{
+ if (!intel_gt_pm_is_awake(gt))
+ return;
+
if (intel_gt_wait_for_idle(gt, I915_GEM_IDLE_TIMEOUT) == -ETIME) {
/*
* Forcibly cancel outstanding work and leave
@@ -215,15 +221,17 @@ static void wait_for_idle(struct intel_gt *gt)
intel_gt_pm_wait_for_idle(gt);
}
-void intel_gt_suspend(struct intel_gt *gt)
+void intel_gt_suspend_late(struct intel_gt *gt)
{
intel_wakeref_t wakeref;
/* We expect to be idle already; but also want to be independent */
- wait_for_idle(gt);
+ intel_gt_suspend_prepare(gt);
with_intel_runtime_pm(>->i915->runtime_pm, wakeref)
intel_rc6_disable(>->rc6);
+
+ intel_uc_suspend(>->uc);
}
void intel_gt_runtime_suspend(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
index 997770d3a968..9967f94b512f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h
@@ -49,8 +49,9 @@ void intel_gt_pm_fini(struct intel_gt *gt);
void intel_gt_sanitize(struct intel_gt *gt, bool force);
+void intel_gt_suspend_prepare(struct intel_gt *gt);
+void intel_gt_suspend_late(struct intel_gt *gt);
int intel_gt_resume(struct intel_gt *gt);
-void intel_gt_suspend(struct intel_gt *gt);
void intel_gt_runtime_suspend(struct intel_gt *gt);
int intel_gt_runtime_resume(struct intel_gt *gt);
diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
index 71184aa72896..b9d743f6adfe 100644
--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -525,6 +525,11 @@ void intel_rc6_init(struct intel_rc6 *rc6)
void intel_rc6_sanitize(struct intel_rc6 *rc6)
{
+ if (rc6->enabled) { /* unbalanced suspend/resume */
+ rpm_get(rc6);
+ rc6->enabled = false;
+ }
+
if (rc6->supported)
__intel_rc6_disable(rc6);
}
diff --git a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
index 87985bd46423..909d117db98f 100644
--- a/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/selftest_gt_pm.c
@@ -13,7 +13,7 @@ static int live_gt_resume(void *arg)
/* Do several suspend/resume cycles to check we don't explode! */
do {
- intel_gt_suspend(gt);
+ intel_gt_suspend_late(gt);
if (gt->rc6.enabled) {
pr_err("rc6 still enabled after suspend!\n");
--
2.23.0
More information about the Intel-gfx-trybot
mailing list