aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2017-07-19 08:54:55 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2017-07-27 16:07:08 -0400
commit4706ca779a723913469a47bbdd63ede01681f0c4 (patch)
tree75193fbf6b37a40438174b5b60e3ce587a261449
parentd34cfebbf9cca8308e7bba3636a1a0fd79131051 (diff)
drm/i915: Unbreak gpu reset vs. modeset locking
Taking the modeset locks unconditionally isn't the greatest idea, because atm that part is still broken and times out (and then atomic keels over). And there's really no reason to do so, the old code didn't do that either. To make the patch a bit simpler let's also nuke 2 cases that are only around for the old mmioflip paths. Atomic nonblocking workers will not die (minus bugs) when a gpu reset happens. And of course this doesn't fix any of the gpu reset vs. modeset deadlock fun, but it at least stop modern CI machines from keeling over all over the place for no reason at all. And we still have the explicit testcases to run the fake gpu reset, so coverage isn't that much worse. v2: Split out additional changes on top, restrict this to purely reducing the critical section of modeset locks. v2: Review from Maarten - update comments - don't oops when state is NULL in intel_finish_reset, but try to at least still drop locks properly. The hw is going to be toast anyway. Fixes: 739748939974 ("drm/i915: Fix modeset handling during gpu reset, v5.") Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20170719125502.25696-3-daniel.vetter@ffwll.ch (cherry picked from commit ce87ea15ebc60a9f8f156b2549f7b2cf7fe48d04) Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c60
1 files changed, 18 insertions, 42 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ae4fb72a3394..e35daae00137 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3427,26 +3427,6 @@ static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
3427 intel_finish_page_flip_cs(dev_priv, crtc->pipe); 3427 intel_finish_page_flip_cs(dev_priv, crtc->pipe);
3428} 3428}
3429 3429
3430static void intel_update_primary_planes(struct drm_device *dev)
3431{
3432 struct drm_crtc *crtc;
3433
3434 for_each_crtc(dev, crtc) {
3435 struct intel_plane *plane = to_intel_plane(crtc->primary);
3436 struct intel_plane_state *plane_state =
3437 to_intel_plane_state(plane->base.state);
3438
3439 if (plane_state->base.visible) {
3440 trace_intel_update_plane(&plane->base,
3441 to_intel_crtc(crtc));
3442
3443 plane->update_plane(plane,
3444 to_intel_crtc_state(crtc->state),
3445 plane_state);
3446 }
3447 }
3448}
3449
3450static int 3430static int
3451__intel_display_resume(struct drm_device *dev, 3431__intel_display_resume(struct drm_device *dev,
3452 struct drm_atomic_state *state, 3432 struct drm_atomic_state *state,
@@ -3499,6 +3479,12 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
3499 struct drm_atomic_state *state; 3479 struct drm_atomic_state *state;
3500 int ret; 3480 int ret;
3501 3481
3482
3483 /* reset doesn't touch the display */
3484 if (!i915.force_reset_modeset_test &&
3485 !gpu_reset_clobbers_display(dev_priv))
3486 return;
3487
3502 /* 3488 /*
3503 * Need mode_config.mutex so that we don't 3489 * Need mode_config.mutex so that we don't
3504 * trample ongoing ->detect() and whatnot. 3490 * trample ongoing ->detect() and whatnot.
@@ -3512,12 +3498,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
3512 3498
3513 drm_modeset_backoff(ctx); 3499 drm_modeset_backoff(ctx);
3514 } 3500 }
3515
3516 /* reset doesn't touch the display, but flips might get nuked anyway, */
3517 if (!i915.force_reset_modeset_test &&
3518 !gpu_reset_clobbers_display(dev_priv))
3519 return;
3520
3521 /* 3501 /*
3522 * Disabling the crtcs gracefully seems nicer. Also the 3502 * Disabling the crtcs gracefully seems nicer. Also the
3523 * g33 docs say we should at least disable all the planes. 3503 * g33 docs say we should at least disable all the planes.
@@ -3547,6 +3527,14 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3547 struct drm_atomic_state *state = dev_priv->modeset_restore_state; 3527 struct drm_atomic_state *state = dev_priv->modeset_restore_state;
3548 int ret; 3528 int ret;
3549 3529
3530 /* reset doesn't touch the display */
3531 if (!i915.force_reset_modeset_test &&
3532 !gpu_reset_clobbers_display(dev_priv))
3533 return;
3534
3535 if (!state)
3536 goto unlock;
3537
3550 /* 3538 /*
3551 * Flips in the rings will be nuked by the reset, 3539 * Flips in the rings will be nuked by the reset,
3552 * so complete all pending flips so that user space 3540 * so complete all pending flips so that user space
@@ -3558,22 +3546,10 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3558 3546
3559 /* reset doesn't touch the display */ 3547 /* reset doesn't touch the display */
3560 if (!gpu_reset_clobbers_display(dev_priv)) { 3548 if (!gpu_reset_clobbers_display(dev_priv)) {
3561 if (!state) { 3549 /* for testing only restore the display */
3562 /* 3550 ret = __intel_display_resume(dev, state, ctx);
3563 * Flips in the rings have been nuked by the reset,
3564 * so update the base address of all primary
3565 * planes to the the last fb to make sure we're
3566 * showing the correct fb after a reset.
3567 *
3568 * FIXME: Atomic will make this obsolete since we won't schedule
3569 * CS-based flips (which might get lost in gpu resets) any more.
3570 */
3571 intel_update_primary_planes(dev);
3572 } else {
3573 ret = __intel_display_resume(dev, state, ctx);
3574 if (ret) 3551 if (ret)
3575 DRM_ERROR("Restoring old state failed with %i\n", ret); 3552 DRM_ERROR("Restoring old state failed with %i\n", ret);
3576 }
3577 } else { 3553 } else {
3578 /* 3554 /*
3579 * The display has been reset as well, 3555 * The display has been reset as well,
@@ -3597,8 +3573,8 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3597 intel_hpd_init(dev_priv); 3573 intel_hpd_init(dev_priv);
3598 } 3574 }
3599 3575
3600 if (state) 3576 drm_atomic_state_put(state);
3601 drm_atomic_state_put(state); 3577unlock:
3602 drm_modeset_drop_locks(ctx); 3578 drm_modeset_drop_locks(ctx);
3603 drm_modeset_acquire_fini(ctx); 3579 drm_modeset_acquire_fini(ctx);
3604 mutex_unlock(&dev->mode_config.mutex); 3580 mutex_unlock(&dev->mode_config.mutex);