* [PATCH 1/2] drm/i915: Fix modeset handling during gpu reset, v2.
@ 2016-05-02 8:57 Maarten Lankhorst
2016-05-02 8:57 ` [PATCH 2/2] drm/i915: Add a way to test the modeset done during gpu reset, v3 Maarten Lankhorst
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Maarten Lankhorst @ 2016-05-02 8:57 UTC (permalink / raw)
To: intel-gfx; +Cc: drm-intel-fixes
This function would call drm_modeset_lock_all, while the suspend/resume
functions already have their own locking. Fix this by factoring out
__intel_display_resume, and calling the atomic helpers for duplicating
atomic state and disabling all crtc's during suspend.
Changes since v1:
- Deal with -EDEADLK right after lock_all and clean up calls
to hw readout.
- Always take all modeset locks so updates during gpu reset are blocked.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.")
Cc: drm-intel-fixes@lists.freedesktop.org
---
drivers/gpu/drm/i915/intel_display.c | 141 ++++++++++++++++++++++-------------
1 file changed, 89 insertions(+), 52 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2f36414702fe..4fb904f2bcf9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3144,27 +3144,83 @@ static void intel_update_primary_planes(struct drm_device *dev)
}
}
+static int
+__intel_display_resume(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ struct drm_crtc_state *crtc_state;
+ struct drm_crtc *crtc;
+ int i;
+
+ intel_modeset_setup_hw_state(dev);
+ i915_redisable_vga(dev);
+
+ if (!state)
+ return 0;
+
+ for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ /*
+ * Force recalculation even if we restore
+ * current state. With fast modeset this may not result
+ * in a modeset when the state is compatible.
+ */
+ crtc_state->mode_changed = true;
+ }
+
+ return drm_atomic_commit(state);
+}
+
void intel_prepare_reset(struct drm_device *dev)
{
+ struct drm_atomic_state *state;
+ struct drm_modeset_acquire_ctx *pctx;
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ int ret;
+
/* no reset support for gen2 */
- if (IS_GEN2(dev))
+ if (IS_GEN2(dev_priv))
return;
- /* reset doesn't touch the display */
- if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
+ drm_modeset_lock_all(dev);
+
+ /* reset doesn't touch the display, but flips might get nuked anyway, */
+ if (INTEL_INFO(dev_priv)->gen >= 5 || IS_G4X(dev_priv))
return;
- drm_modeset_lock_all(dev);
+ pctx = dev->mode_config.acquire_ctx;
+
/*
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
*/
- intel_display_suspend(dev);
+
+ state = drm_atomic_helper_duplicate_state(dev, pctx);
+ if (IS_ERR(state)) {
+ ret = PTR_ERR(state);
+ state = NULL;
+ DRM_ERROR("Duplicating state failed with %i\n", ret);
+ goto err;
+ }
+
+ ret = drm_atomic_helper_disable_all(dev, pctx);
+ if (ret) {
+ DRM_ERROR("Suspending crtc's failed with %i\n", ret);
+ goto err;
+ }
+
+ dev_priv->modeset_restore_state = state;
+ state->acquire_ctx = pctx;
+ return;
+
+err:
+ drm_atomic_state_free(state);
}
void intel_finish_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
+ struct drm_atomic_state *state = dev_priv->modeset_restore_state;
+ int ret;
/*
* Flips in the rings will be nuked by the reset,
@@ -3177,6 +3233,8 @@ void intel_finish_reset(struct drm_device *dev)
if (IS_GEN2(dev))
return;
+ dev_priv->modeset_restore_state = NULL;
+
/* reset doesn't touch the display */
if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) {
/*
@@ -3189,26 +3247,27 @@ void intel_finish_reset(struct drm_device *dev)
* CS-based flips (which might get lost in gpu resets) any more.
*/
intel_update_primary_planes(dev);
- return;
- }
-
- /*
- * The display has been reset as well,
- * so need a full re-initialization.
- */
- intel_runtime_pm_disable_interrupts(dev_priv);
- intel_runtime_pm_enable_interrupts(dev_priv);
+ } else {
+ /*
+ * The display has been reset as well,
+ * so need a full re-initialization.
+ */
+ intel_runtime_pm_disable_interrupts(dev_priv);
+ intel_runtime_pm_enable_interrupts(dev_priv);
- intel_modeset_init_hw(dev);
+ intel_modeset_init_hw(dev);
- spin_lock_irq(&dev_priv->irq_lock);
- if (dev_priv->display.hpd_irq_setup)
- dev_priv->display.hpd_irq_setup(dev);
- spin_unlock_irq(&dev_priv->irq_lock);
+ spin_lock_irq(&dev_priv->irq_lock);
+ if (dev_priv->display.hpd_irq_setup)
+ dev_priv->display.hpd_irq_setup(dev);
+ spin_unlock_irq(&dev_priv->irq_lock);
- intel_display_resume(dev);
+ ret = __intel_display_resume(dev, state);
+ if (ret)
+ DRM_ERROR("Restoring old state failed with %i\n", ret);
- intel_hpd_init(dev_priv);
+ intel_hpd_init(dev_priv);
+ }
drm_modeset_unlock_all(dev);
}
@@ -15957,9 +16016,10 @@ void intel_display_resume(struct drm_device *dev)
struct drm_atomic_state *state = dev_priv->modeset_restore_state;
struct drm_modeset_acquire_ctx ctx;
int ret;
- bool setup = false;
dev_priv->modeset_restore_state = NULL;
+ if (state)
+ state->acquire_ctx = &ctx;
/*
* This is a cludge because with real atomic modeset mode_config.mutex
@@ -15970,40 +16030,17 @@ void intel_display_resume(struct drm_device *dev)
mutex_lock(&dev->mode_config.mutex);
drm_modeset_acquire_init(&ctx, 0);
-retry:
- ret = drm_modeset_lock_all_ctx(dev, &ctx);
-
- if (ret == 0 && !setup) {
- setup = true;
-
- intel_modeset_setup_hw_state(dev);
- i915_redisable_vga(dev);
- }
-
- if (ret == 0 && state) {
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- int i;
-
- state->acquire_ctx = &ctx;
-
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- /*
- * Force recalculation even if we restore
- * current state. With fast modeset this may not result
- * in a modeset when the state is compatible.
- */
- crtc_state->mode_changed = true;
- }
-
- ret = drm_atomic_commit(state);
- }
+ while (1) {
+ ret = drm_modeset_lock_all_ctx(dev, &ctx);
+ if (ret != -EDEADLK)
+ break;
- if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
- goto retry;
}
+ ret = __intel_display_resume(dev, state);
+ WARN_ON(ret == -EDEADLK);
+
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
mutex_unlock(&dev->mode_config.mutex);
--
2.5.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/2] drm/i915: Add a way to test the modeset done during gpu reset, v3. 2016-05-02 8:57 [PATCH 1/2] drm/i915: Fix modeset handling during gpu reset, v2 Maarten Lankhorst @ 2016-05-02 8:57 ` Maarten Lankhorst 2016-05-02 9:59 ` ✗ Fi.CI.BAT: failure for series starting with [1/2] drm/i915: Fix modeset handling during gpu reset, v2 Patchwork 2016-05-06 13:06 ` [PATCH 1/2] " Ville Syrjälä 2 siblings, 0 replies; 10+ messages in thread From: Maarten Lankhorst @ 2016-05-02 8:57 UTC (permalink / raw) To: intel-gfx Add force_reset_modeset_test as a parameter to force the modeset path during gpu reset. This allows a IGT test to set the knob and trigger a hang to force the gpu reset, even on platforms that wouldn't otherwise require it. Changes since v1: - Split out fix to separate commit. Changes since v2: - This commit is purely about force_reset_modeset_test now. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Testcase: drv_hangman.reset-with-forced-modeset --- drivers/gpu/drm/i915/i915_params.c | 6 ++++++ drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_display.c | 30 +++++++++++++++++++----------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 383c076919ed..ec3a03bfe3b0 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -45,6 +45,7 @@ struct i915_params i915 __read_mostly = { .fastboot = 0, .prefault_disable = 0, .load_detect_test = 0, + .force_reset_modeset_test = 0, .reset = true, .invert_brightness = 0, .disable_display = 0, @@ -159,6 +160,11 @@ MODULE_PARM_DESC(load_detect_test, "Force-enable the VGA load detect code for testing (default:false). " "For developers only."); +module_param_named_unsafe(force_reset_modeset_test, i915.force_reset_modeset_test, bool, 0600); +MODULE_PARM_DESC(force_reset_modeset_test, + "Force a modeset during gpu reset for testing (default:false). " + "For developers only."); + module_param_named_unsafe(invert_brightness, i915.invert_brightness, int, 0600); MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness " diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 65e73dd7d970..76c556a30461 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -55,6 +55,7 @@ struct i915_params { bool fastboot; bool prefault_disable; bool load_detect_test; + bool force_reset_modeset_test; bool reset; bool disable_display; bool enable_guc_submission; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4fb904f2bcf9..153039cc3ae8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3184,7 +3184,8 @@ void intel_prepare_reset(struct drm_device *dev) drm_modeset_lock_all(dev); /* reset doesn't touch the display, but flips might get nuked anyway, */ - if (INTEL_INFO(dev_priv)->gen >= 5 || IS_G4X(dev_priv)) + if (!i915.force_reset_modeset_test && + (INTEL_INFO(dev_priv)->gen >= 5 || IS_G4X(dev_priv))) return; pctx = dev->mode_config.acquire_ctx; @@ -3237,16 +3238,23 @@ void intel_finish_reset(struct drm_device *dev) /* reset doesn't touch the display */ if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) { - /* - * Flips in the rings have been nuked by the reset, - * so update the base address of all primary - * planes to the the last fb to make sure we're - * showing the correct fb after a reset. - * - * FIXME: Atomic will make this obsolete since we won't schedule - * CS-based flips (which might get lost in gpu resets) any more. - */ - intel_update_primary_planes(dev); + if (!state) { + /* + * Flips in the rings have been nuked by the reset, + * so update the base address of all primary + * planes to the the last fb to make sure we're + * showing the correct fb after a reset. + * + * FIXME: Atomic will make this obsolete since we won't schedule + * CS-based flips (which might get lost in gpu resets) any more. + */ + intel_update_primary_planes(dev); + } else { + ret = __intel_display_resume(dev, state); + + if (ret) + DRM_ERROR("Restoring old state failed with %i\n", ret); + } } else { /* * The display has been reset as well, -- 2.5.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
* ✗ Fi.CI.BAT: failure for series starting with [1/2] drm/i915: Fix modeset handling during gpu reset, v2. 2016-05-02 8:57 [PATCH 1/2] drm/i915: Fix modeset handling during gpu reset, v2 Maarten Lankhorst 2016-05-02 8:57 ` [PATCH 2/2] drm/i915: Add a way to test the modeset done during gpu reset, v3 Maarten Lankhorst @ 2016-05-02 9:59 ` Patchwork 2016-05-06 13:06 ` [PATCH 1/2] " Ville Syrjälä 2 siblings, 0 replies; 10+ messages in thread From: Patchwork @ 2016-05-02 9:59 UTC (permalink / raw) To: Maarten Lankhorst; +Cc: intel-gfx == Series Details == Series: series starting with [1/2] drm/i915: Fix modeset handling during gpu reset, v2. URL : https://patchwork.freedesktop.org/series/6600/ State : failure == Summary == Series 6600v1 Series without cover letter http://patchwork.freedesktop.org/api/1.0/series/6600/revisions/1/mbox/ Test drv_hangman: Subgroup error-state-basic: pass -> INCOMPLETE (snb-x220t) pass -> INCOMPLETE (bdw-nuci7-2) pass -> INCOMPLETE (ilk-hp8440p) Test gem_ringfill: Subgroup basic-default-hang: pass -> INCOMPLETE (snb-dellxps) pass -> INCOMPLETE (skl-nuci5) Test kms_pipe_crc_basic: Subgroup hang-read-crc-pipe-a: pass -> INCOMPLETE (bdw-ultra) pass -> INCOMPLETE (skl-i7k-2) pass -> INCOMPLETE (byt-nuc) Subgroup hang-read-crc-pipe-b: skip -> INCOMPLETE (bsw-nuc-2) pass -> INCOMPLETE (hsw-gt2) pass -> INCOMPLETE (ivb-t430s) bdw-nuci7-2 total:5 pass:4 dwarn:0 dfail:0 fail:0 skip:0 bdw-ultra total:95 pass:83 dwarn:0 dfail:0 fail:0 skip:11 bsw-nuc-2 total:87 pass:67 dwarn:0 dfail:0 fail:0 skip:19 byt-nuc total:53 pass:42 dwarn:0 dfail:0 fail:1 skip:9 hsw-brixbox total:21 pass:16 dwarn:0 dfail:0 fail:0 skip:4 hsw-gt2 total:12 pass:11 dwarn:0 dfail:0 fail:0 skip:0 ilk-hp8440p total:43 pass:33 dwarn:0 dfail:0 fail:0 skip:9 ivb-t430s total:35 pass:31 dwarn:0 dfail:0 fail:0 skip:3 skl-i7k-2 total:35 pass:30 dwarn:0 dfail:0 fail:0 skip:4 skl-nuci5 total:48 pass:45 dwarn:0 dfail:0 fail:0 skip:2 snb-dellxps total:6 pass:4 dwarn:0 dfail:0 fail:0 skip:1 snb-x220t total:69 pass:55 dwarn:0 dfail:0 fail:0 skip:13 Results at /archive/results/CI_IGT_test/Patchwork_2123/ 5256d5ce241debab2267faf6dc2d5ad9eaca9554 drm-intel-nightly: 2016y-05m-02d-07h-51m-16s UTC integration manifest 7410f53 drm/i915: Add a way to test the modeset done during gpu reset, v3. 089f414 drm/i915: Fix modeset handling during gpu reset, v2. _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] drm/i915: Fix modeset handling during gpu reset, v2. 2016-05-02 8:57 [PATCH 1/2] drm/i915: Fix modeset handling during gpu reset, v2 Maarten Lankhorst 2016-05-02 8:57 ` [PATCH 2/2] drm/i915: Add a way to test the modeset done during gpu reset, v3 Maarten Lankhorst 2016-05-02 9:59 ` ✗ Fi.CI.BAT: failure for series starting with [1/2] drm/i915: Fix modeset handling during gpu reset, v2 Patchwork @ 2016-05-06 13:06 ` Ville Syrjälä 2016-05-09 10:29 ` Maarten Lankhorst 2016-05-09 11:04 ` [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3 Maarten Lankhorst 2 siblings, 2 replies; 10+ messages in thread From: Ville Syrjälä @ 2016-05-06 13:06 UTC (permalink / raw) To: Maarten Lankhorst; +Cc: intel-gfx, drm-intel-fixes On Mon, May 02, 2016 at 10:57:01AM +0200, Maarten Lankhorst wrote: > This function would call drm_modeset_lock_all, while the suspend/resume > functions already have their own locking. Fix this by factoring out > __intel_display_resume, and calling the atomic helpers for duplicating > atomic state and disabling all crtc's during suspend. > > Changes since v1: > - Deal with -EDEADLK right after lock_all and clean up calls > to hw readout. > - Always take all modeset locks so updates during gpu reset are blocked. Found this patch by accident. --in-reply-to would have helped a bit. > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") > Cc: drm-intel-fixes@lists.freedesktop.org > --- > drivers/gpu/drm/i915/intel_display.c | 141 ++++++++++++++++++++++------------- > 1 file changed, 89 insertions(+), 52 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 2f36414702fe..4fb904f2bcf9 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3144,27 +3144,83 @@ static void intel_update_primary_planes(struct drm_device *dev) > } > } > > +static int > +__intel_display_resume(struct drm_device *dev, > + struct drm_atomic_state *state) > +{ > + struct drm_crtc_state *crtc_state; > + struct drm_crtc *crtc; > + int i; > + > + intel_modeset_setup_hw_state(dev); > + i915_redisable_vga(dev); > + > + if (!state) > + return 0; > + > + for_each_crtc_in_state(state, crtc, crtc_state, i) { > + /* > + * Force recalculation even if we restore > + * current state. With fast modeset this may not result > + * in a modeset when the state is compatible. > + */ > + crtc_state->mode_changed = true; > + } > + > + return drm_atomic_commit(state); The -EDEADLK warn could be here so we don't have to duplicate it in two places perhaps? Extracting __intel_display_reset() could also be a separate patch to make this stuff a bit easier to review. Oh and BTW resume is also broken on platforms that have the force pipe A quirk. I do have some patches lined up to nuke that quirk for good, which I should probably post sooner rather than later. But those have at least a theoretical chance of regressing something, so in the meantime I think we'll still need to fix this thing for the normal resume path as well. > +} > + > void intel_prepare_reset(struct drm_device *dev) > { > + struct drm_atomic_state *state; > + struct drm_modeset_acquire_ctx *pctx; > + struct drm_i915_private *dev_priv = to_i915(dev); > + int ret; > + > /* no reset support for gen2 */ > - if (IS_GEN2(dev)) > + if (IS_GEN2(dev_priv)) > return; > > - /* reset doesn't touch the display */ > - if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) > + drm_modeset_lock_all(dev); Isn't that going to clash with the locking in intel_update_primary_planes() ? > + > + /* reset doesn't touch the display, but flips might get nuked anyway, */ > + if (INTEL_INFO(dev_priv)->gen >= 5 || IS_G4X(dev_priv)) > return; > > - drm_modeset_lock_all(dev); > + pctx = dev->mode_config.acquire_ctx; Still looks like power context. > + > /* > * Disabling the crtcs gracefully seems nicer. Also the > * g33 docs say we should at least disable all the planes. > */ > - intel_display_suspend(dev); > + > + state = drm_atomic_helper_duplicate_state(dev, pctx); > + if (IS_ERR(state)) { > + ret = PTR_ERR(state); > + state = NULL; > + DRM_ERROR("Duplicating state failed with %i\n", ret); > + goto err; > + } > + > + ret = drm_atomic_helper_disable_all(dev, pctx); > + if (ret) { > + DRM_ERROR("Suspending crtc's failed with %i\n", ret); > + goto err; > + } > + > + dev_priv->modeset_restore_state = state; > + state->acquire_ctx = pctx; > + return; > + > +err: > + drm_atomic_state_free(state); > } > > void intel_finish_reset(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = to_i915(dev); > + struct drm_atomic_state *state = dev_priv->modeset_restore_state; > + int ret; > > /* > * Flips in the rings will be nuked by the reset, > @@ -3177,6 +3233,8 @@ void intel_finish_reset(struct drm_device *dev) > if (IS_GEN2(dev)) > return; > > + dev_priv->modeset_restore_state = NULL; > + > /* reset doesn't touch the display */ > if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) { > /* > @@ -3189,26 +3247,27 @@ void intel_finish_reset(struct drm_device *dev) > * CS-based flips (which might get lost in gpu resets) any more. > */ > intel_update_primary_planes(dev); > - return; > - } > - > - /* > - * The display has been reset as well, > - * so need a full re-initialization. > - */ > - intel_runtime_pm_disable_interrupts(dev_priv); > - intel_runtime_pm_enable_interrupts(dev_priv); > + } else { > + /* > + * The display has been reset as well, > + * so need a full re-initialization. > + */ > + intel_runtime_pm_disable_interrupts(dev_priv); > + intel_runtime_pm_enable_interrupts(dev_priv); > > - intel_modeset_init_hw(dev); > + intel_modeset_init_hw(dev); > > - spin_lock_irq(&dev_priv->irq_lock); > - if (dev_priv->display.hpd_irq_setup) > - dev_priv->display.hpd_irq_setup(dev); > - spin_unlock_irq(&dev_priv->irq_lock); > + spin_lock_irq(&dev_priv->irq_lock); > + if (dev_priv->display.hpd_irq_setup) > + dev_priv->display.hpd_irq_setup(dev); > + spin_unlock_irq(&dev_priv->irq_lock); > > - intel_display_resume(dev); > + ret = __intel_display_resume(dev, state); > + if (ret) > + DRM_ERROR("Restoring old state failed with %i\n", ret); > > - intel_hpd_init(dev_priv); > + intel_hpd_init(dev_priv); > + } > > drm_modeset_unlock_all(dev); > } > @@ -15957,9 +16016,10 @@ void intel_display_resume(struct drm_device *dev) > struct drm_atomic_state *state = dev_priv->modeset_restore_state; > struct drm_modeset_acquire_ctx ctx; > int ret; > - bool setup = false; > > dev_priv->modeset_restore_state = NULL; > + if (state) > + state->acquire_ctx = &ctx; > > /* > * This is a cludge because with real atomic modeset mode_config.mutex > @@ -15970,40 +16030,17 @@ void intel_display_resume(struct drm_device *dev) > mutex_lock(&dev->mode_config.mutex); > drm_modeset_acquire_init(&ctx, 0); > > -retry: > - ret = drm_modeset_lock_all_ctx(dev, &ctx); > - > - if (ret == 0 && !setup) { > - setup = true; > - > - intel_modeset_setup_hw_state(dev); > - i915_redisable_vga(dev); > - } > - > - if (ret == 0 && state) { > - struct drm_crtc_state *crtc_state; > - struct drm_crtc *crtc; > - int i; > - > - state->acquire_ctx = &ctx; > - > - for_each_crtc_in_state(state, crtc, crtc_state, i) { > - /* > - * Force recalculation even if we restore > - * current state. With fast modeset this may not result > - * in a modeset when the state is compatible. > - */ > - crtc_state->mode_changed = true; > - } > - > - ret = drm_atomic_commit(state); > - } > + while (1) { > + ret = drm_modeset_lock_all_ctx(dev, &ctx); > + if (ret != -EDEADLK) > + break; > > - if (ret == -EDEADLK) { > drm_modeset_backoff(&ctx); > - goto retry; > } > > + ret = __intel_display_resume(dev, state); Shouldn't we skip this call if the lock_all failed? > + WARN_ON(ret == -EDEADLK); > + > drm_modeset_drop_locks(&ctx); > drm_modeset_acquire_fini(&ctx); > mutex_unlock(&dev->mode_config.mutex); > -- > 2.5.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] drm/i915: Fix modeset handling during gpu reset, v2. 2016-05-06 13:06 ` [PATCH 1/2] " Ville Syrjälä @ 2016-05-09 10:29 ` Maarten Lankhorst 2016-05-09 11:04 ` [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3 Maarten Lankhorst 1 sibling, 0 replies; 10+ messages in thread From: Maarten Lankhorst @ 2016-05-09 10:29 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx, drm-intel-fixes Op 06-05-16 om 15:06 schreef Ville Syrjälä: > On Mon, May 02, 2016 at 10:57:01AM +0200, Maarten Lankhorst wrote: >> This function would call drm_modeset_lock_all, while the suspend/resume >> functions already have their own locking. Fix this by factoring out >> __intel_display_resume, and calling the atomic helpers for duplicating >> atomic state and disabling all crtc's during suspend. >> >> Changes since v1: >> - Deal with -EDEADLK right after lock_all and clean up calls >> to hw readout. >> - Always take all modeset locks so updates during gpu reset are blocked. > Found this patch by accident. --in-reply-to would have helped a bit. > >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> >> Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") >> Cc: drm-intel-fixes@lists.freedesktop.org >> --- >> drivers/gpu/drm/i915/intel_display.c | 141 ++++++++++++++++++++++------------- >> 1 file changed, 89 insertions(+), 52 deletions(-) >> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c >> index 2f36414702fe..4fb904f2bcf9 100644 >> --- a/drivers/gpu/drm/i915/intel_display.c >> +++ b/drivers/gpu/drm/i915/intel_display.c >> @@ -3144,27 +3144,83 @@ static void intel_update_primary_planes(struct drm_device *dev) >> } >> } >> >> +static int >> +__intel_display_resume(struct drm_device *dev, >> + struct drm_atomic_state *state) >> +{ >> + struct drm_crtc_state *crtc_state; >> + struct drm_crtc *crtc; >> + int i; >> + >> + intel_modeset_setup_hw_state(dev); >> + i915_redisable_vga(dev); >> + >> + if (!state) >> + return 0; >> + >> + for_each_crtc_in_state(state, crtc, crtc_state, i) { >> + /* >> + * Force recalculation even if we restore >> + * current state. With fast modeset this may not result >> + * in a modeset when the state is compatible. >> + */ >> + crtc_state->mode_changed = true; >> + } >> + >> + return drm_atomic_commit(state); > The -EDEADLK warn could be here so we don't have to duplicate it in two > places perhaps? Extracting __intel_display_reset() could also be a separate > patch to make this stuff a bit easier to review. > > Oh and BTW resume is also broken on platforms that have the force pipe A > quirk. I do have some patches lined up to nuke that quirk for good, which > I should probably post sooner rather than later. But those have at least > a theoretical chance of regressing something, so in the meantime I think > we'll still need to fix this thing for the normal resume path as well. > >> +} >> + >> void intel_prepare_reset(struct drm_device *dev) >> { >> + struct drm_atomic_state *state; >> + struct drm_modeset_acquire_ctx *pctx; >> + struct drm_i915_private *dev_priv = to_i915(dev); >> + int ret; >> + >> /* no reset support for gen2 */ >> - if (IS_GEN2(dev)) >> + if (IS_GEN2(dev_priv)) >> return; >> >> - /* reset doesn't touch the display */ >> - if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) >> + drm_modeset_lock_all(dev); > Isn't that going to clash with the locking in > intel_update_primary_planes() ? Oops indeed, thanks for catching. >> + >> + /* reset doesn't touch the display, but flips might get nuked anyway, */ >> + if (INTEL_INFO(dev_priv)->gen >= 5 || IS_G4X(dev_priv)) >> return; >> >> - drm_modeset_lock_all(dev); >> + pctx = dev->mode_config.acquire_ctx; > Still looks like power context. Will change to ctx. >> + >> /* >> * Disabling the crtcs gracefully seems nicer. Also the >> * g33 docs say we should at least disable all the planes. >> */ >> - intel_display_suspend(dev); >> + >> + state = drm_atomic_helper_duplicate_state(dev, pctx); >> + if (IS_ERR(state)) { >> + ret = PTR_ERR(state); >> + state = NULL; >> + DRM_ERROR("Duplicating state failed with %i\n", ret); >> + goto err; >> + } >> + >> + ret = drm_atomic_helper_disable_all(dev, pctx); >> + if (ret) { >> + DRM_ERROR("Suspending crtc's failed with %i\n", ret); >> + goto err; >> + } >> + >> + dev_priv->modeset_restore_state = state; >> + state->acquire_ctx = pctx; >> + return; >> + >> +err: >> + drm_atomic_state_free(state); >> } >> >> void intel_finish_reset(struct drm_device *dev) >> { >> struct drm_i915_private *dev_priv = to_i915(dev); >> + struct drm_atomic_state *state = dev_priv->modeset_restore_state; >> + int ret; >> >> /* >> * Flips in the rings will be nuked by the reset, >> @@ -3177,6 +3233,8 @@ void intel_finish_reset(struct drm_device *dev) >> if (IS_GEN2(dev)) >> return; >> >> + dev_priv->modeset_restore_state = NULL; >> + >> /* reset doesn't touch the display */ >> if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) { >> /* >> @@ -3189,26 +3247,27 @@ void intel_finish_reset(struct drm_device *dev) >> * CS-based flips (which might get lost in gpu resets) any more. >> */ >> intel_update_primary_planes(dev); >> - return; >> - } >> - >> - /* >> - * The display has been reset as well, >> - * so need a full re-initialization. >> - */ >> - intel_runtime_pm_disable_interrupts(dev_priv); >> - intel_runtime_pm_enable_interrupts(dev_priv); >> + } else { >> + /* >> + * The display has been reset as well, >> + * so need a full re-initialization. >> + */ >> + intel_runtime_pm_disable_interrupts(dev_priv); >> + intel_runtime_pm_enable_interrupts(dev_priv); >> >> - intel_modeset_init_hw(dev); >> + intel_modeset_init_hw(dev); >> >> - spin_lock_irq(&dev_priv->irq_lock); >> - if (dev_priv->display.hpd_irq_setup) >> - dev_priv->display.hpd_irq_setup(dev); >> - spin_unlock_irq(&dev_priv->irq_lock); >> + spin_lock_irq(&dev_priv->irq_lock); >> + if (dev_priv->display.hpd_irq_setup) >> + dev_priv->display.hpd_irq_setup(dev); >> + spin_unlock_irq(&dev_priv->irq_lock); >> >> - intel_display_resume(dev); >> + ret = __intel_display_resume(dev, state); >> + if (ret) >> + DRM_ERROR("Restoring old state failed with %i\n", ret); >> >> - intel_hpd_init(dev_priv); >> + intel_hpd_init(dev_priv); >> + } >> >> drm_modeset_unlock_all(dev); >> } >> @@ -15957,9 +16016,10 @@ void intel_display_resume(struct drm_device *dev) >> struct drm_atomic_state *state = dev_priv->modeset_restore_state; >> struct drm_modeset_acquire_ctx ctx; >> int ret; >> - bool setup = false; >> >> dev_priv->modeset_restore_state = NULL; >> + if (state) >> + state->acquire_ctx = &ctx; >> >> /* >> * This is a cludge because with real atomic modeset mode_config.mutex >> @@ -15970,40 +16030,17 @@ void intel_display_resume(struct drm_device *dev) >> mutex_lock(&dev->mode_config.mutex); >> drm_modeset_acquire_init(&ctx, 0); >> >> -retry: >> - ret = drm_modeset_lock_all_ctx(dev, &ctx); >> - >> - if (ret == 0 && !setup) { >> - setup = true; >> - >> - intel_modeset_setup_hw_state(dev); >> - i915_redisable_vga(dev); >> - } >> - >> - if (ret == 0 && state) { >> - struct drm_crtc_state *crtc_state; >> - struct drm_crtc *crtc; >> - int i; >> - >> - state->acquire_ctx = &ctx; >> - >> - for_each_crtc_in_state(state, crtc, crtc_state, i) { >> - /* >> - * Force recalculation even if we restore >> - * current state. With fast modeset this may not result >> - * in a modeset when the state is compatible. >> - */ >> - crtc_state->mode_changed = true; >> - } >> - >> - ret = drm_atomic_commit(state); >> - } >> + while (1) { >> + ret = drm_modeset_lock_all_ctx(dev, &ctx); >> + if (ret != -EDEADLK) >> + break; >> >> - if (ret == -EDEADLK) { >> drm_modeset_backoff(&ctx); >> - goto retry; >> } >> >> + ret = __intel_display_resume(dev, state); > Shouldn't we skip this call if the lock_all failed? I guess for paranoia I could, but the locking can only fail with EDEADLK or EALREADY. EALREADY is mapped to 0 since multiple locking calls are allowed, so can realistically only fail with -EDEADLK, won't even be able to fail with -EINTR in the future since s/r is not interruptible. _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3. 2016-05-06 13:06 ` [PATCH 1/2] " Ville Syrjälä 2016-05-09 10:29 ` Maarten Lankhorst @ 2016-05-09 11:04 ` Maarten Lankhorst 2016-05-09 12:54 ` Ville Syrjälä 1 sibling, 1 reply; 10+ messages in thread From: Maarten Lankhorst @ 2016-05-09 11:04 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx, drm-intel-fixes This function would call drm_modeset_lock_all, while the suspend/resume functions already have their own locking. Fix this by factoring out __intel_display_resume, and calling the atomic helpers for duplicating atomic state and disabling all crtc's during suspend. Changes since v1: - Deal with -EDEADLK right after lock_all and clean up calls to hw readout. - Always take all modeset locks so updates during gpu reset are blocked. Changes since v2: - Fix deadlock in intel_update_primary_planes. - Move WARN_ON(EDEADLK) to __intel_display_resume. - pctx -> ctx - only call __intel_display_resume on success in intel_display_resume. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") Cc: drm-intel-fixes@lists.freedesktop.org --- drivers/gpu/drm/i915/intel_display.c | 150 ++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 14e05091c397..6faa529f35df 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3130,41 +3130,96 @@ static void intel_update_primary_planes(struct drm_device *dev) for_each_crtc(dev, crtc) { struct intel_plane *plane = to_intel_plane(crtc->primary); - struct intel_plane_state *plane_state; - - drm_modeset_lock_crtc(crtc, &plane->base); - plane_state = to_intel_plane_state(plane->base.state); + struct intel_plane_state *plane_state = + to_intel_plane_state(plane->base.state); if (plane_state->visible) plane->update_plane(&plane->base, to_intel_crtc_state(crtc->state), plane_state); + } +} + +static int +__intel_display_resume(struct drm_device *dev, + struct drm_atomic_state *state) +{ + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + int i, ret; + + intel_modeset_setup_hw_state(dev); + i915_redisable_vga(dev); - drm_modeset_unlock_crtc(crtc); + if (!state) + return 0; + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + /* + * Force recalculation even if we restore + * current state. With fast modeset this may not result + * in a modeset when the state is compatible. + */ + crtc_state->mode_changed = true; } + + ret = drm_atomic_commit(state); + + WARN_ON(ret == -EDEADLK); + return ret; } void intel_prepare_reset(struct drm_device *dev) { + struct drm_atomic_state *state; + struct drm_modeset_acquire_ctx *ctx; + struct drm_i915_private *dev_priv = to_i915(dev); + int ret; + /* no reset support for gen2 */ - if (IS_GEN2(dev)) + if (IS_GEN2(dev_priv)) return; - /* reset doesn't touch the display */ - if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) + drm_modeset_lock_all(dev); + + /* reset doesn't touch the display, but flips might get nuked anyway, */ + if (INTEL_INFO(dev_priv)->gen >= 5 || IS_G4X(dev_priv)) return; - drm_modeset_lock_all(dev); + ctx = dev->mode_config.acquire_ctx; + /* * Disabling the crtcs gracefully seems nicer. Also the * g33 docs say we should at least disable all the planes. */ - intel_display_suspend(dev); + + state = drm_atomic_helper_duplicate_state(dev, ctx); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + state = NULL; + DRM_ERROR("Duplicating state failed with %i\n", ret); + goto err; + } + + ret = drm_atomic_helper_disable_all(dev, ctx); + if (ret) { + DRM_ERROR("Suspending crtc's failed with %i\n", ret); + goto err; + } + + dev_priv->modeset_restore_state = state; + state->acquire_ctx = ctx; + return; + +err: + drm_atomic_state_free(state); } void intel_finish_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_atomic_state *state = dev_priv->modeset_restore_state; + int ret; /* * Flips in the rings will be nuked by the reset, @@ -3177,6 +3232,8 @@ void intel_finish_reset(struct drm_device *dev) if (IS_GEN2(dev)) return; + dev_priv->modeset_restore_state = NULL; + /* reset doesn't touch the display */ if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) { /* @@ -3189,26 +3246,27 @@ void intel_finish_reset(struct drm_device *dev) * CS-based flips (which might get lost in gpu resets) any more. */ intel_update_primary_planes(dev); - return; - } - - /* - * The display has been reset as well, - * so need a full re-initialization. - */ - intel_runtime_pm_disable_interrupts(dev_priv); - intel_runtime_pm_enable_interrupts(dev_priv); + } else { + /* + * The display has been reset as well, + * so need a full re-initialization. + */ + intel_runtime_pm_disable_interrupts(dev_priv); + intel_runtime_pm_enable_interrupts(dev_priv); - intel_modeset_init_hw(dev); + intel_modeset_init_hw(dev); - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hpd_irq_setup) - dev_priv->display.hpd_irq_setup(dev); - spin_unlock_irq(&dev_priv->irq_lock); + spin_lock_irq(&dev_priv->irq_lock); + if (dev_priv->display.hpd_irq_setup) + dev_priv->display.hpd_irq_setup(dev); + spin_unlock_irq(&dev_priv->irq_lock); - intel_display_resume(dev); + ret = __intel_display_resume(dev, state); + if (ret) + DRM_ERROR("Restoring old state failed with %i\n", ret); - intel_hpd_init(dev_priv); + intel_hpd_init(dev_priv); + } drm_modeset_unlock_all(dev); } @@ -15955,9 +16013,10 @@ void intel_display_resume(struct drm_device *dev) struct drm_atomic_state *state = dev_priv->modeset_restore_state; struct drm_modeset_acquire_ctx ctx; int ret; - bool setup = false; dev_priv->modeset_restore_state = NULL; + if (state) + state->acquire_ctx = &ctx; /* * This is a cludge because with real atomic modeset mode_config.mutex @@ -15968,40 +16027,17 @@ void intel_display_resume(struct drm_device *dev) mutex_lock(&dev->mode_config.mutex); drm_modeset_acquire_init(&ctx, 0); -retry: - ret = drm_modeset_lock_all_ctx(dev, &ctx); - - if (ret == 0 && !setup) { - setup = true; - - intel_modeset_setup_hw_state(dev); - i915_redisable_vga(dev); - } - - if (ret == 0 && state) { - struct drm_crtc_state *crtc_state; - struct drm_crtc *crtc; - int i; - - state->acquire_ctx = &ctx; - - for_each_crtc_in_state(state, crtc, crtc_state, i) { - /* - * Force recalculation even if we restore - * current state. With fast modeset this may not result - * in a modeset when the state is compatible. - */ - crtc_state->mode_changed = true; - } - - ret = drm_atomic_commit(state); - } + while (1) { + ret = drm_modeset_lock_all_ctx(dev, &ctx); + if (ret != -EDEADLK) + break; - if (ret == -EDEADLK) { drm_modeset_backoff(&ctx); - goto retry; } + if (!ret) + ret = __intel_display_resume(dev, state); + drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); mutex_unlock(&dev->mode_config.mutex); -- 2.5.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3. 2016-05-09 11:04 ` [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3 Maarten Lankhorst @ 2016-05-09 12:54 ` Ville Syrjälä 2016-05-10 7:48 ` Daniel Vetter 0 siblings, 1 reply; 10+ messages in thread From: Ville Syrjälä @ 2016-05-09 12:54 UTC (permalink / raw) To: Maarten Lankhorst; +Cc: intel-gfx, drm-intel-fixes On Mon, May 09, 2016 at 01:04:21PM +0200, Maarten Lankhorst wrote: > This function would call drm_modeset_lock_all, while the suspend/resume > functions already have their own locking. Fix this by factoring out > __intel_display_resume, and calling the atomic helpers for duplicating > atomic state and disabling all crtc's during suspend. > > Changes since v1: > - Deal with -EDEADLK right after lock_all and clean up calls > to hw readout. > - Always take all modeset locks so updates during gpu reset are blocked. > Changes since v2: > - Fix deadlock in intel_update_primary_planes. > - Move WARN_ON(EDEADLK) to __intel_display_resume. > - pctx -> ctx > - only call __intel_display_resume on success in intel_display_resume. > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") > Cc: drm-intel-fixes@lists.freedesktop.org > --- > drivers/gpu/drm/i915/intel_display.c | 150 ++++++++++++++++++++++------------- > 1 file changed, 93 insertions(+), 57 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 14e05091c397..6faa529f35df 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3130,41 +3130,96 @@ static void intel_update_primary_planes(struct drm_device *dev) > > for_each_crtc(dev, crtc) { > struct intel_plane *plane = to_intel_plane(crtc->primary); > - struct intel_plane_state *plane_state; > - > - drm_modeset_lock_crtc(crtc, &plane->base); > - plane_state = to_intel_plane_state(plane->base.state); > + struct intel_plane_state *plane_state = > + to_intel_plane_state(plane->base.state); > > if (plane_state->visible) > plane->update_plane(&plane->base, > to_intel_crtc_state(crtc->state), > plane_state); > + } > +} > + > +static int > +__intel_display_resume(struct drm_device *dev, > + struct drm_atomic_state *state) > +{ > + struct drm_crtc_state *crtc_state; > + struct drm_crtc *crtc; > + int i, ret; > + > + intel_modeset_setup_hw_state(dev); > + i915_redisable_vga(dev); > > - drm_modeset_unlock_crtc(crtc); > + if (!state) > + return 0; Thank you diff for making things illegible. I'm still not convinced we should be changing the locking scheme here, especially in what's supposed to be just a fix. In general, I'm not sure we want ->detect() and other irrelevant stuff to block the GPU reset. The nice thing about g4x+ reset so far has been that it's almost unnoticeable. Of course if it's a genuine GPU hang the screen will probably have been frozen for quite a while when we initiate the reset, so perhaps that's not a huge real world issue. Anyways, I kinda just want this fixed now, so I'll just toss in my Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> BTW as a followup I think we would actually want gen2 to take the g4x+ path. There won't have been a reset, but the flips in the ring will still never complete so our idea of frontbuffer may be out of sync with the hardware, and so we should fix it up. > + > + for_each_crtc_in_state(state, crtc, crtc_state, i) { > + /* > + * Force recalculation even if we restore > + * current state. With fast modeset this may not result > + * in a modeset when the state is compatible. > + */ > + crtc_state->mode_changed = true; > } > + > + ret = drm_atomic_commit(state); > + > + WARN_ON(ret == -EDEADLK); > + return ret; > } > > void intel_prepare_reset(struct drm_device *dev) > { > + struct drm_atomic_state *state; > + struct drm_modeset_acquire_ctx *ctx; > + struct drm_i915_private *dev_priv = to_i915(dev); > + int ret; > + > /* no reset support for gen2 */ > - if (IS_GEN2(dev)) > + if (IS_GEN2(dev_priv)) > return; > > - /* reset doesn't touch the display */ > - if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) > + drm_modeset_lock_all(dev); > + > + /* reset doesn't touch the display, but flips might get nuked anyway, */ > + if (INTEL_INFO(dev_priv)->gen >= 5 || IS_G4X(dev_priv)) > return; > > - drm_modeset_lock_all(dev); > + ctx = dev->mode_config.acquire_ctx; > + > /* > * Disabling the crtcs gracefully seems nicer. Also the > * g33 docs say we should at least disable all the planes. > */ > - intel_display_suspend(dev); > + > + state = drm_atomic_helper_duplicate_state(dev, ctx); > + if (IS_ERR(state)) { > + ret = PTR_ERR(state); > + state = NULL; > + DRM_ERROR("Duplicating state failed with %i\n", ret); > + goto err; > + } > + > + ret = drm_atomic_helper_disable_all(dev, ctx); > + if (ret) { > + DRM_ERROR("Suspending crtc's failed with %i\n", ret); > + goto err; > + } > + > + dev_priv->modeset_restore_state = state; > + state->acquire_ctx = ctx; > + return; > + > +err: > + drm_atomic_state_free(state); > } > > void intel_finish_reset(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = to_i915(dev); > + struct drm_atomic_state *state = dev_priv->modeset_restore_state; > + int ret; > > /* > * Flips in the rings will be nuked by the reset, > @@ -3177,6 +3232,8 @@ void intel_finish_reset(struct drm_device *dev) > if (IS_GEN2(dev)) > return; > > + dev_priv->modeset_restore_state = NULL; > + > /* reset doesn't touch the display */ > if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) { > /* > @@ -3189,26 +3246,27 @@ void intel_finish_reset(struct drm_device *dev) > * CS-based flips (which might get lost in gpu resets) any more. > */ > intel_update_primary_planes(dev); > - return; > - } > - > - /* > - * The display has been reset as well, > - * so need a full re-initialization. > - */ > - intel_runtime_pm_disable_interrupts(dev_priv); > - intel_runtime_pm_enable_interrupts(dev_priv); > + } else { > + /* > + * The display has been reset as well, > + * so need a full re-initialization. > + */ > + intel_runtime_pm_disable_interrupts(dev_priv); > + intel_runtime_pm_enable_interrupts(dev_priv); > > - intel_modeset_init_hw(dev); > + intel_modeset_init_hw(dev); > > - spin_lock_irq(&dev_priv->irq_lock); > - if (dev_priv->display.hpd_irq_setup) > - dev_priv->display.hpd_irq_setup(dev); > - spin_unlock_irq(&dev_priv->irq_lock); > + spin_lock_irq(&dev_priv->irq_lock); > + if (dev_priv->display.hpd_irq_setup) > + dev_priv->display.hpd_irq_setup(dev); > + spin_unlock_irq(&dev_priv->irq_lock); > > - intel_display_resume(dev); > + ret = __intel_display_resume(dev, state); > + if (ret) > + DRM_ERROR("Restoring old state failed with %i\n", ret); > > - intel_hpd_init(dev_priv); > + intel_hpd_init(dev_priv); > + } > > drm_modeset_unlock_all(dev); > } > @@ -15955,9 +16013,10 @@ void intel_display_resume(struct drm_device *dev) > struct drm_atomic_state *state = dev_priv->modeset_restore_state; > struct drm_modeset_acquire_ctx ctx; > int ret; > - bool setup = false; > > dev_priv->modeset_restore_state = NULL; > + if (state) > + state->acquire_ctx = &ctx; > > /* > * This is a cludge because with real atomic modeset mode_config.mutex > @@ -15968,40 +16027,17 @@ void intel_display_resume(struct drm_device *dev) > mutex_lock(&dev->mode_config.mutex); > drm_modeset_acquire_init(&ctx, 0); > > -retry: > - ret = drm_modeset_lock_all_ctx(dev, &ctx); > - > - if (ret == 0 && !setup) { > - setup = true; > - > - intel_modeset_setup_hw_state(dev); > - i915_redisable_vga(dev); > - } > - > - if (ret == 0 && state) { > - struct drm_crtc_state *crtc_state; > - struct drm_crtc *crtc; > - int i; > - > - state->acquire_ctx = &ctx; > - > - for_each_crtc_in_state(state, crtc, crtc_state, i) { > - /* > - * Force recalculation even if we restore > - * current state. With fast modeset this may not result > - * in a modeset when the state is compatible. > - */ > - crtc_state->mode_changed = true; > - } > - > - ret = drm_atomic_commit(state); > - } > + while (1) { > + ret = drm_modeset_lock_all_ctx(dev, &ctx); > + if (ret != -EDEADLK) > + break; > > - if (ret == -EDEADLK) { > drm_modeset_backoff(&ctx); > - goto retry; > } > > + if (!ret) > + ret = __intel_display_resume(dev, state); > + > drm_modeset_drop_locks(&ctx); > drm_modeset_acquire_fini(&ctx); > mutex_unlock(&dev->mode_config.mutex); > -- > 2.5.5 > -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3. 2016-05-09 12:54 ` Ville Syrjälä @ 2016-05-10 7:48 ` Daniel Vetter 2016-05-10 17:08 ` Maarten Lankhorst 2016-05-11 8:35 ` [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v4 Maarten Lankhorst 0 siblings, 2 replies; 10+ messages in thread From: Daniel Vetter @ 2016-05-10 7:48 UTC (permalink / raw) To: Ville Syrjälä; +Cc: drm-intel-fixes, intel-gfx On Mon, May 09, 2016 at 03:54:15PM +0300, Ville Syrjälä wrote: > On Mon, May 09, 2016 at 01:04:21PM +0200, Maarten Lankhorst wrote: > > This function would call drm_modeset_lock_all, while the suspend/resume > > functions already have their own locking. Fix this by factoring out > > __intel_display_resume, and calling the atomic helpers for duplicating > > atomic state and disabling all crtc's during suspend. > > > > Changes since v1: > > - Deal with -EDEADLK right after lock_all and clean up calls > > to hw readout. > > - Always take all modeset locks so updates during gpu reset are blocked. > > Changes since v2: > > - Fix deadlock in intel_update_primary_planes. > > - Move WARN_ON(EDEADLK) to __intel_display_resume. > > - pctx -> ctx > > - only call __intel_display_resume on success in intel_display_resume. > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > > Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") > > Cc: drm-intel-fixes@lists.freedesktop.org > > --- > > drivers/gpu/drm/i915/intel_display.c | 150 ++++++++++++++++++++++------------- > > 1 file changed, 93 insertions(+), 57 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > > index 14e05091c397..6faa529f35df 100644 > > --- a/drivers/gpu/drm/i915/intel_display.c > > +++ b/drivers/gpu/drm/i915/intel_display.c > > @@ -3130,41 +3130,96 @@ static void intel_update_primary_planes(struct drm_device *dev) > > > > for_each_crtc(dev, crtc) { > > struct intel_plane *plane = to_intel_plane(crtc->primary); > > - struct intel_plane_state *plane_state; > > - > > - drm_modeset_lock_crtc(crtc, &plane->base); > > - plane_state = to_intel_plane_state(plane->base.state); > > + struct intel_plane_state *plane_state = > > + to_intel_plane_state(plane->base.state); > > > > if (plane_state->visible) > > plane->update_plane(&plane->base, > > to_intel_crtc_state(crtc->state), > > plane_state); > > + } > > +} > > + > > +static int > > +__intel_display_resume(struct drm_device *dev, > > + struct drm_atomic_state *state) > > +{ > > + struct drm_crtc_state *crtc_state; > > + struct drm_crtc *crtc; > > + int i, ret; > > + > > + intel_modeset_setup_hw_state(dev); > > + i915_redisable_vga(dev); > > > > - drm_modeset_unlock_crtc(crtc); > > + if (!state) > > + return 0; > > Thank you diff for making things illegible. > > I'm still not convinced we should be changing the locking scheme > here, especially in what's supposed to be just a fix. > > In general, I'm not sure we want ->detect() and other irrelevant > stuff to block the GPU reset. The nice thing about g4x+ reset so > far has been that it's almost unnoticeable. Of course if it's a > genuine GPU hang the screen will probably have been frozen for > quite a while when we initiate the reset, so perhaps that's not > a huge real world issue. We don't really need dev->mode_config.mutex for atomic commits, so taking that out and use drm_modeset_lock_all_ctx would give you that. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3. 2016-05-10 7:48 ` Daniel Vetter @ 2016-05-10 17:08 ` Maarten Lankhorst 2016-05-11 8:35 ` [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v4 Maarten Lankhorst 1 sibling, 0 replies; 10+ messages in thread From: Maarten Lankhorst @ 2016-05-10 17:08 UTC (permalink / raw) To: Daniel Vetter, Ville Syrjälä; +Cc: intel-gfx, drm-intel-fixes Op 10-05-16 om 09:48 schreef Daniel Vetter: > On Mon, May 09, 2016 at 03:54:15PM +0300, Ville Syrjälä wrote: >> On Mon, May 09, 2016 at 01:04:21PM +0200, Maarten Lankhorst wrote: >>> This function would call drm_modeset_lock_all, while the suspend/resume >>> functions already have their own locking. Fix this by factoring out >>> __intel_display_resume, and calling the atomic helpers for duplicating >>> atomic state and disabling all crtc's during suspend. >>> >>> Changes since v1: >>> - Deal with -EDEADLK right after lock_all and clean up calls >>> to hw readout. >>> - Always take all modeset locks so updates during gpu reset are blocked. >>> Changes since v2: >>> - Fix deadlock in intel_update_primary_planes. >>> - Move WARN_ON(EDEADLK) to __intel_display_resume. >>> - pctx -> ctx >>> - only call __intel_display_resume on success in intel_display_resume. >>> >>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> >>> Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") >>> Cc: drm-intel-fixes@lists.freedesktop.org >>> --- >>> drivers/gpu/drm/i915/intel_display.c | 150 ++++++++++++++++++++++------------- >>> 1 file changed, 93 insertions(+), 57 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c >>> index 14e05091c397..6faa529f35df 100644 >>> --- a/drivers/gpu/drm/i915/intel_display.c >>> +++ b/drivers/gpu/drm/i915/intel_display.c >>> @@ -3130,41 +3130,96 @@ static void intel_update_primary_planes(struct drm_device *dev) >>> >>> for_each_crtc(dev, crtc) { >>> struct intel_plane *plane = to_intel_plane(crtc->primary); >>> - struct intel_plane_state *plane_state; >>> - >>> - drm_modeset_lock_crtc(crtc, &plane->base); >>> - plane_state = to_intel_plane_state(plane->base.state); >>> + struct intel_plane_state *plane_state = >>> + to_intel_plane_state(plane->base.state); >>> >>> if (plane_state->visible) >>> plane->update_plane(&plane->base, >>> to_intel_crtc_state(crtc->state), >>> plane_state); >>> + } >>> +} >>> + >>> +static int >>> +__intel_display_resume(struct drm_device *dev, >>> + struct drm_atomic_state *state) >>> +{ >>> + struct drm_crtc_state *crtc_state; >>> + struct drm_crtc *crtc; >>> + int i, ret; >>> + >>> + intel_modeset_setup_hw_state(dev); >>> + i915_redisable_vga(dev); >>> >>> - drm_modeset_unlock_crtc(crtc); >>> + if (!state) >>> + return 0; >> Thank you diff for making things illegible. >> >> I'm still not convinced we should be changing the locking scheme >> here, especially in what's supposed to be just a fix. >> >> In general, I'm not sure we want ->detect() and other irrelevant >> stuff to block the GPU reset. The nice thing about g4x+ reset so >> far has been that it's almost unnoticeable. Of course if it's a >> genuine GPU hang the screen will probably have been frozen for >> quite a while when we initiate the reset, so perhaps that's not >> a huge real world issue. > We don't really need dev->mode_config.mutex for atomic commits, so taking > that out and use drm_modeset_lock_all_ctx would give you that. > -Daniel Except that i915 still complains if we don't hold mode_config.mutex commit ea49c9acf2db7082f0406bb3a570cc6bad37082b Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Date: Tue Feb 16 15:27:42 2016 +0100 drm/i915: Lock mode_config.mutex in intel_display_resume. So keeping it for now would be better. _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v4. 2016-05-10 7:48 ` Daniel Vetter 2016-05-10 17:08 ` Maarten Lankhorst @ 2016-05-11 8:35 ` Maarten Lankhorst 1 sibling, 0 replies; 10+ messages in thread From: Maarten Lankhorst @ 2016-05-11 8:35 UTC (permalink / raw) To: Daniel Vetter, Ville Syrjälä; +Cc: intel-gfx, drm-intel-fixes Op 10-05-16 om 09:48 schreef Daniel Vetter: > On Mon, May 09, 2016 at 03:54:15PM +0300, Ville Syrjälä wrote: >> On Mon, May 09, 2016 at 01:04:21PM +0200, Maarten Lankhorst wrote: >>> This function would call drm_modeset_lock_all, while the suspend/resume >>> functions already have their own locking. Fix this by factoring out >>> __intel_display_resume, and calling the atomic helpers for duplicating >>> atomic state and disabling all crtc's during suspend. >>> >>> Changes since v1: >>> - Deal with -EDEADLK right after lock_all and clean up calls >>> to hw readout. >>> - Always take all modeset locks so updates during gpu reset are blocked. >>> Changes since v2: >>> - Fix deadlock in intel_update_primary_planes. >>> - Move WARN_ON(EDEADLK) to __intel_display_resume. >>> - pctx -> ctx >>> - only call __intel_display_resume on success in intel_display_resume. >>> >>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> >>> Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") >>> Cc: drm-intel-fixes@lists.freedesktop.org >>> --- >>> drivers/gpu/drm/i915/intel_display.c | 150 ++++++++++++++++++++++------------- >>> 1 file changed, 93 insertions(+), 57 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c >>> index 14e05091c397..6faa529f35df 100644 >>> --- a/drivers/gpu/drm/i915/intel_display.c >>> +++ b/drivers/gpu/drm/i915/intel_display.c >>> @@ -3130,41 +3130,96 @@ static void intel_update_primary_planes(struct drm_device *dev) >>> >>> for_each_crtc(dev, crtc) { >>> struct intel_plane *plane = to_intel_plane(crtc->primary); >>> - struct intel_plane_state *plane_state; >>> - >>> - drm_modeset_lock_crtc(crtc, &plane->base); >>> - plane_state = to_intel_plane_state(plane->base.state); >>> + struct intel_plane_state *plane_state = >>> + to_intel_plane_state(plane->base.state); >>> >>> if (plane_state->visible) >>> plane->update_plane(&plane->base, >>> to_intel_crtc_state(crtc->state), >>> plane_state); >>> + } >>> +} >>> + >>> +static int >>> +__intel_display_resume(struct drm_device *dev, >>> + struct drm_atomic_state *state) >>> +{ >>> + struct drm_crtc_state *crtc_state; >>> + struct drm_crtc *crtc; >>> + int i, ret; >>> + >>> + intel_modeset_setup_hw_state(dev); >>> + i915_redisable_vga(dev); >>> >>> - drm_modeset_unlock_crtc(crtc); >>> + if (!state) >>> + return 0; >> Thank you diff for making things illegible. >> >> I'm still not convinced we should be changing the locking scheme >> here, especially in what's supposed to be just a fix. >> >> In general, I'm not sure we want ->detect() and other irrelevant >> stuff to block the GPU reset. The nice thing about g4x+ reset so >> far has been that it's almost unnoticeable. Of course if it's a >> genuine GPU hang the screen will probably have been frozen for >> quite a while when we initiate the reset, so perhaps that's not >> a huge real world issue. > We don't really need dev->mode_config.mutex for atomic commits, so taking > that out and use drm_modeset_lock_all_ctx would give you that. > -Daniel ---->8---- This function would call drm_modeset_lock_all, while the suspend/resume functions already have their own locking. Fix this by factoring out __intel_display_resume, and calling the atomic helpers for duplicating atomic state and disabling all crtc's during suspend. Changes since v1: - Deal with -EDEADLK right after lock_all and clean up calls to hw readout. - Always take all modeset locks so updates during gpu reset are blocked. Changes since v2: - Fix deadlock in intel_update_primary_planes. - Move WARN_ON(EDEADLK) to __intel_display_resume. - pctx -> ctx - only call __intel_display_resume on success in intel_display_resume. Changes since v3: - Rebase on top of dev_priv -> dev change. - Use drm_modeset_lock_all_ctx instead of drm_modeset_lock_all. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") Cc: drm-intel-fixes@lists.freedesktop.org --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 164 +++++++++++++++++++++++------------ 2 files changed, 109 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4abd39f32c0f..422e551937f7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1835,6 +1835,7 @@ struct drm_i915_private { enum modeset_restore modeset_restore; struct mutex modeset_restore_lock; struct drm_atomic_state *modeset_restore_state; + struct drm_modeset_acquire_ctx reset_ctx; struct list_head vm_list; /* Global list of all address spaces */ struct i915_ggtt ggtt; /* VM representing the global address space */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 138ed1aa3938..e88a942787c5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3130,40 +3130,109 @@ static void intel_update_primary_planes(struct drm_device *dev) for_each_crtc(dev, crtc) { struct intel_plane *plane = to_intel_plane(crtc->primary); - struct intel_plane_state *plane_state; - - drm_modeset_lock_crtc(crtc, &plane->base); - plane_state = to_intel_plane_state(plane->base.state); + struct intel_plane_state *plane_state = + to_intel_plane_state(plane->base.state); if (plane_state->visible) plane->update_plane(&plane->base, to_intel_crtc_state(crtc->state), plane_state); + } +} + +static int +__intel_display_resume(struct drm_device *dev, + struct drm_atomic_state *state) +{ + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + int i, ret; + + intel_modeset_setup_hw_state(dev); + i915_redisable_vga(dev); - drm_modeset_unlock_crtc(crtc); + if (!state) + return 0; + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + /* + * Force recalculation even if we restore + * current state. With fast modeset this may not result + * in a modeset when the state is compatible. + */ + crtc_state->mode_changed = true; } + + ret = drm_atomic_commit(state); + + WARN_ON(ret == -EDEADLK); + return ret; } void intel_prepare_reset(struct drm_i915_private *dev_priv) { + struct drm_atomic_state *state; + struct drm_modeset_acquire_ctx *ctx; + int ret; + /* no reset support for gen2 */ if (IS_GEN2(dev_priv)) return; - /* reset doesn't touch the display */ + ctx = &dev_priv->reset_ctx; + + /* + * This is a cludge because with real atomic modeset mode_config.mutex + * won't be taken. Unfortunately some probed state like + * audio_codec_enable is still protected by mode_config.mutex, so lock + * it here for now. + */ + mutex_lock(&dev_priv->dev->mode_config.mutex); + drm_modeset_acquire_init(ctx, 0); + while (1) { + ret = drm_modeset_lock_all_ctx(dev_priv->dev, ctx); + if (ret != -EDEADLK) + break; + + drm_modeset_backoff(ctx); + } + + /* reset doesn't touch the display, but flips might get nuked anyway, */ if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) return; - drm_modeset_lock_all(dev_priv->dev); /* * Disabling the crtcs gracefully seems nicer. Also the * g33 docs say we should at least disable all the planes. */ - intel_display_suspend(dev_priv->dev); + state = drm_atomic_helper_duplicate_state(dev_priv->dev, ctx); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + state = NULL; + DRM_ERROR("Duplicating state failed with %i\n", ret); + goto err; + } + + ret = drm_atomic_helper_disable_all(dev_priv->dev, ctx); + if (ret) { + DRM_ERROR("Suspending crtc's failed with %i\n", ret); + goto err; + } + + dev_priv->modeset_restore_state = state; + state->acquire_ctx = ctx; + return; + +err: + drm_atomic_state_free(state); } void intel_finish_reset(struct drm_i915_private *dev_priv) { + struct drm_atomic_state *state = dev_priv->modeset_restore_state; + struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx; + int ret; + /* * Flips in the rings will be nuked by the reset, * so complete all pending flips so that user space @@ -3175,6 +3244,8 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) if (IS_GEN2(dev_priv)) return; + dev_priv->modeset_restore_state = NULL; + /* reset doesn't touch the display */ if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) { /* @@ -3187,28 +3258,31 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) * CS-based flips (which might get lost in gpu resets) any more. */ intel_update_primary_planes(dev_priv->dev); - return; - } - - /* - * The display has been reset as well, - * so need a full re-initialization. - */ - intel_runtime_pm_disable_interrupts(dev_priv); - intel_runtime_pm_enable_interrupts(dev_priv); + } else { + /* + * The display has been reset as well, + * so need a full re-initialization. + */ + intel_runtime_pm_disable_interrupts(dev_priv); + intel_runtime_pm_enable_interrupts(dev_priv); - intel_modeset_init_hw(dev_priv->dev); + intel_modeset_init_hw(dev_priv->dev); - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hpd_irq_setup) - dev_priv->display.hpd_irq_setup(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + spin_lock_irq(&dev_priv->irq_lock); + if (dev_priv->display.hpd_irq_setup) + dev_priv->display.hpd_irq_setup(dev_priv); + spin_unlock_irq(&dev_priv->irq_lock); - intel_display_resume(dev_priv->dev); + ret = __intel_display_resume(dev_priv->dev, state); + if (ret) + DRM_ERROR("Restoring old state failed with %i\n", ret); - intel_hpd_init(dev_priv); + intel_hpd_init(dev_priv); + } - drm_modeset_unlock_all(dev_priv->dev); + drm_modeset_drop_locks(ctx); + drm_modeset_acquire_fini(ctx); + mutex_unlock(&dev_priv->dev->mode_config.mutex); } static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) @@ -15957,9 +16031,10 @@ void intel_display_resume(struct drm_device *dev) struct drm_atomic_state *state = dev_priv->modeset_restore_state; struct drm_modeset_acquire_ctx ctx; int ret; - bool setup = false; dev_priv->modeset_restore_state = NULL; + if (state) + state->acquire_ctx = &ctx; /* * This is a cludge because with real atomic modeset mode_config.mutex @@ -15970,40 +16045,17 @@ void intel_display_resume(struct drm_device *dev) mutex_lock(&dev->mode_config.mutex); drm_modeset_acquire_init(&ctx, 0); -retry: - ret = drm_modeset_lock_all_ctx(dev, &ctx); - - if (ret == 0 && !setup) { - setup = true; - - intel_modeset_setup_hw_state(dev); - i915_redisable_vga(dev); - } - - if (ret == 0 && state) { - struct drm_crtc_state *crtc_state; - struct drm_crtc *crtc; - int i; - - state->acquire_ctx = &ctx; - - for_each_crtc_in_state(state, crtc, crtc_state, i) { - /* - * Force recalculation even if we restore - * current state. With fast modeset this may not result - * in a modeset when the state is compatible. - */ - crtc_state->mode_changed = true; - } - - ret = drm_atomic_commit(state); - } + while (1) { + ret = drm_modeset_lock_all_ctx(dev, &ctx); + if (ret != -EDEADLK) + break; - if (ret == -EDEADLK) { drm_modeset_backoff(&ctx); - goto retry; } + if (!ret) + ret = __intel_display_resume(dev, state); + drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); mutex_unlock(&dev->mode_config.mutex); -- 2.5.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2016-05-11 8:35 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-05-02 8:57 [PATCH 1/2] drm/i915: Fix modeset handling during gpu reset, v2 Maarten Lankhorst 2016-05-02 8:57 ` [PATCH 2/2] drm/i915: Add a way to test the modeset done during gpu reset, v3 Maarten Lankhorst 2016-05-02 9:59 ` ✗ Fi.CI.BAT: failure for series starting with [1/2] drm/i915: Fix modeset handling during gpu reset, v2 Patchwork 2016-05-06 13:06 ` [PATCH 1/2] " Ville Syrjälä 2016-05-09 10:29 ` Maarten Lankhorst 2016-05-09 11:04 ` [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v3 Maarten Lankhorst 2016-05-09 12:54 ` Ville Syrjälä 2016-05-10 7:48 ` Daniel Vetter 2016-05-10 17:08 ` Maarten Lankhorst 2016-05-11 8:35 ` [PATCH v3 1/2] drm/i915: Fix modeset handling during gpu reset, v4 Maarten Lankhorst
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox