* [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock
@ 2017-07-15 11:39 Daniel Vetter
2017-07-15 11:40 ` [PATCH 1/7] drm/i915: Nuke legacy flip queueing code Daniel Vetter
` (7 more replies)
0 siblings, 8 replies; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:39 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter
Hi all,
Here's my patch series to unbreak the gpu reset vs. modeset deadlock.
First things first: This needs Maarten's swap_state series, otherwise the atomic
commit machinery will sooner or later shoot itself, keel over and take the
entire kernel with it.
There's two important bits in here:
- Reduce the scope of modeset locking, we accidentally encumbered all platforms
with this problem instead of just pre-g4x (and igt testing in special
test-only modes).
- Decouple the TDR from the atomic machinery. I've done this in 2 stage, first
explicit wedge at the right spot, as a proof of concept and for testing. Then
refine that hammer into just unbreaking the depency and so making sure TDR can
do it's thing everywhere.
Seems to all work, but definitely needs more testing.
The only glitch left now is that on affected platforms you might spot a short
glitch until TDR has done its thing and rendering and atomic are in lockstep
again.
Cheers, Daniel
Daniel Vetter (7):
drm/i915: Nuke legacy flip queueing code
drm/i915: Unbreak gpu reset vs. modeset locking
drm/atomic-helper: add sync_all helper for gpu reset
drm/i915: only disable outputs in simulated gpu resets
drm/i915: Avoid the gpu reset vs. modeset deadlock
drm/i915: Push i915_sw_fence_wait into the nonblocking atomic commit
drm/i915: More surgically unbreak the modeset vs reset deadlock
drivers/gpu/drm/drm_atomic_helper.c | 38 ++
drivers/gpu/drm/i915/i915_drv.h | 6 +-
drivers/gpu/drm/i915/intel_display.c | 768 +++--------------------------------
include/drm/drm_atomic_helper.h | 1 +
4 files changed, 100 insertions(+), 713 deletions(-)
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/7] drm/i915: Nuke legacy flip queueing code
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
@ 2017-07-15 11:40 ` Daniel Vetter
2017-07-15 11:40 ` [PATCH 2/7] drm/i915: Unbreak gpu reset vs. modeset locking Daniel Vetter
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:40 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Daniel Vetter
Just a very minimal patch to nuke that code. Lots of the flip
interrupt handling stuff is still around.
Cc: 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>
---
drivers/gpu/drm/i915/i915_drv.h | 5 -
drivers/gpu/drm/i915/intel_display.c | 656 -----------------------------------
2 files changed, 661 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a1eeb489b3f8..bdee66ca23af 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -715,11 +715,6 @@ struct drm_i915_display_funcs {
void (*fdi_link_train)(struct intel_crtc *crtc,
const struct intel_crtc_state *crtc_state);
void (*init_clock_gating)(struct drm_i915_private *dev_priv);
- int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags);
void (*hpd_irq_setup)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */
/* cursor updates */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 451a14f7d822..f69333b8995c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2664,20 +2664,6 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
return false;
}
-/* Update plane->state->fb to match plane->fb after driver-internal updates */
-static void
-update_state_fb(struct drm_plane *plane)
-{
- if (plane->fb == plane->state->fb)
- return;
-
- if (plane->state->fb)
- drm_framebuffer_unreference(plane->state->fb);
- plane->state->fb = plane->fb;
- if (plane->state->fb)
- drm_framebuffer_reference(plane->state->fb);
-}
-
static void
intel_set_plane_visible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state,
@@ -10153,35 +10139,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
kfree(intel_crtc);
}
-static void intel_unpin_work_fn(struct work_struct *__work)
-{
- struct intel_flip_work *work =
- container_of(__work, struct intel_flip_work, unpin_work);
- struct intel_crtc *crtc = to_intel_crtc(work->crtc);
- struct drm_device *dev = crtc->base.dev;
- struct drm_plane *primary = crtc->base.primary;
-
- if (is_mmio_work(work))
- flush_work(&work->mmio_work);
-
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_vma(work->old_vma);
- i915_gem_object_put(work->pending_flip_obj);
- mutex_unlock(&dev->struct_mutex);
-
- i915_gem_request_put(work->flip_queued_req);
-
- intel_frontbuffer_flip_complete(to_i915(dev),
- to_intel_plane(primary)->frontbuffer_bit);
- intel_fbc_post_update(crtc);
- drm_framebuffer_unreference(work->old_fb);
-
- BUG_ON(atomic_read(&crtc->unpin_work_count) == 0);
- atomic_dec(&crtc->unpin_work_count);
-
- kfree(work);
-}
-
/* Is 'a' after or equal to 'b'? */
static bool g4x_flip_count_after_eq(u32 a, u32 b)
{
@@ -10326,346 +10283,6 @@ static inline void intel_mark_page_flip_active(struct intel_crtc *crtc,
atomic_set(&work->pending, 1);
}
-static int intel_gen2_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 flip_mask, *cs;
-
- cs = intel_ring_begin(req, 6);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* Can't queue multiple flips, so wait for the previous
- * one to finish before executing the next.
- */
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
- *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
- *cs++ = MI_NOOP;
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = 0; /* aux display base address, unused */
-
- return 0;
-}
-
-static int intel_gen3_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 flip_mask, *cs;
-
- cs = intel_ring_begin(req, 6);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
- *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
- *cs++ = MI_NOOP;
- *cs++ = MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = MI_NOOP;
-
- return 0;
-}
-
-static int intel_gen4_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 pf, pipesrc, *cs;
-
- cs = intel_ring_begin(req, 4);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* i965+ uses the linear or tiled offsets from the
- * Display Registers (which do not change across a page-flip)
- * so we need only reprogram the base address.
- */
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset |
- intel_fb_modifier_to_tiling(fb->modifier);
-
- /* XXX Enabling the panel-fitter across page-flip is so far
- * untested on non-native modes, so ignore it for now.
- * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
- */
- pf = 0;
- pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
- *cs++ = pf | pipesrc;
-
- return 0;
-}
-
-static int intel_gen6_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 pf, pipesrc, *cs;
-
- cs = intel_ring_begin(req, 4);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
- *cs++ = intel_crtc->flip_work->gtt_offset;
-
- /* Contrary to the suggestions in the documentation,
- * "Enable Panel Fitter" does not seem to be required when page
- * flipping with a non-native mode, and worse causes a normal
- * modeset to fail.
- * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
- */
- pf = 0;
- pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
- *cs++ = pf | pipesrc;
-
- return 0;
-}
-
-static int intel_gen7_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 *cs, plane_bit = 0;
- int len, ret;
-
- switch (intel_crtc->plane) {
- case PLANE_A:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
- break;
- case PLANE_B:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
- break;
- case PLANE_C:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
- break;
- default:
- WARN_ONCE(1, "unknown plane in flip command\n");
- return -ENODEV;
- }
-
- len = 4;
- if (req->engine->id == RCS) {
- len += 6;
- /*
- * On Gen 8, SRM is now taking an extra dword to accommodate
- * 48bits addresses, and we need a NOOP for the batch size to
- * stay even.
- */
- if (IS_GEN8(dev_priv))
- len += 2;
- }
-
- /*
- * BSpec MI_DISPLAY_FLIP for IVB:
- * "The full packet must be contained within the same cache line."
- *
- * Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same
- * cacheline, if we ever start emitting more commands before
- * the MI_DISPLAY_FLIP we may need to first emit everything else,
- * then do the cacheline alignment, and finally emit the
- * MI_DISPLAY_FLIP.
- */
- ret = intel_ring_cacheline_align(req);
- if (ret)
- return ret;
-
- cs = intel_ring_begin(req, len);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* Unmask the flip-done completion message. Note that the bspec says that
- * we should do this for both the BCS and RCS, and that we must not unmask
- * more than one flip event at any time (or ensure that one flip message
- * can be sent by waiting for flip-done prior to queueing new flips).
- * Experimentation says that BCS works despite DERRMR masking all
- * flip-done completion events and that unmasking all planes at once
- * for the RCS also doesn't appear to drop events. Setting the DERRMR
- * to zero does lead to lockups within MI_DISPLAY_FLIP.
- */
- if (req->engine->id == RCS) {
- *cs++ = MI_LOAD_REGISTER_IMM(1);
- *cs++ = i915_mmio_reg_offset(DERRMR);
- *cs++ = ~(DERRMR_PIPEA_PRI_FLIP_DONE |
- DERRMR_PIPEB_PRI_FLIP_DONE |
- DERRMR_PIPEC_PRI_FLIP_DONE);
- if (IS_GEN8(dev_priv))
- *cs++ = MI_STORE_REGISTER_MEM_GEN8 |
- MI_SRM_LRM_GLOBAL_GTT;
- else
- *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
- *cs++ = i915_mmio_reg_offset(DERRMR);
- *cs++ = i915_ggtt_offset(req->engine->scratch) + 256;
- if (IS_GEN8(dev_priv)) {
- *cs++ = 0;
- *cs++ = MI_NOOP;
- }
- }
-
- *cs++ = MI_DISPLAY_FLIP_I915 | plane_bit;
- *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = MI_NOOP;
-
- return 0;
-}
-
-static bool use_mmio_flip(struct intel_engine_cs *engine,
- struct drm_i915_gem_object *obj)
-{
- /*
- * This is not being used for older platforms, because
- * non-availability of flip done interrupt forces us to use
- * CS flips. Older platforms derive flip done using some clever
- * tricks involving the flip_pending status bits and vblank irqs.
- * So using MMIO flips there would disrupt this mechanism.
- */
-
- if (engine == NULL)
- return true;
-
- if (INTEL_GEN(engine->i915) < 5)
- return false;
-
- if (i915.use_mmio_flip < 0)
- return false;
- else if (i915.use_mmio_flip > 0)
- return true;
- else if (i915.enable_execlists)
- return true;
-
- return engine != i915_gem_object_last_write_engine(obj);
-}
-
-static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
- unsigned int rotation,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = intel_crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
- const enum pipe pipe = intel_crtc->pipe;
- u32 ctl, stride = skl_plane_stride(fb, 0, rotation);
-
- ctl = I915_READ(PLANE_CTL(pipe, 0));
- ctl &= ~PLANE_CTL_TILED_MASK;
- switch (fb->modifier) {
- case DRM_FORMAT_MOD_LINEAR:
- break;
- case I915_FORMAT_MOD_X_TILED:
- ctl |= PLANE_CTL_TILED_X;
- break;
- case I915_FORMAT_MOD_Y_TILED:
- ctl |= PLANE_CTL_TILED_Y;
- break;
- case I915_FORMAT_MOD_Yf_TILED:
- ctl |= PLANE_CTL_TILED_YF;
- break;
- default:
- MISSING_CASE(fb->modifier);
- }
-
- /*
- * Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
- * PLANE_SURF updates, the update is then guaranteed to be atomic.
- */
- I915_WRITE(PLANE_CTL(pipe, 0), ctl);
- I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
-
- I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset);
- POSTING_READ(PLANE_SURF(pipe, 0));
-}
-
-static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = intel_crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
- i915_reg_t reg = DSPCNTR(intel_crtc->plane);
- u32 dspcntr;
-
- dspcntr = I915_READ(reg);
-
- if (fb->modifier == I915_FORMAT_MOD_X_TILED)
- dspcntr |= DISPPLANE_TILED;
- else
- dspcntr &= ~DISPPLANE_TILED;
-
- I915_WRITE(reg, dspcntr);
-
- I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset);
- POSTING_READ(DSPSURF(intel_crtc->plane));
-}
-
-static void intel_mmio_flip_work_func(struct work_struct *w)
-{
- struct intel_flip_work *work =
- container_of(w, struct intel_flip_work, mmio_work);
- struct intel_crtc *crtc = to_intel_crtc(work->crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_framebuffer *intel_fb =
- to_intel_framebuffer(crtc->base.primary->fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
-
- WARN_ON(i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT, NULL) < 0);
-
- intel_pipe_update_start(crtc);
-
- if (INTEL_GEN(dev_priv) >= 9)
- skl_do_mmio_flip(crtc, work->rotation, work);
- else
- /* use_mmio_flip() retricts MMIO flips to ilk+ */
- ilk_do_mmio_flip(crtc, work);
-
- intel_pipe_update_end(crtc, work);
-}
-
-static int intel_default_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- return -ENODEV;
-}
-
static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv,
struct intel_crtc *intel_crtc,
struct intel_flip_work *work)
@@ -10732,251 +10349,6 @@ void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
spin_unlock(&dev->event_lock);
}
-__maybe_unused
-static int intel_crtc_page_flip(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t page_flip_flags)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *old_fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_plane *primary = crtc->primary;
- enum pipe pipe = intel_crtc->pipe;
- struct intel_flip_work *work;
- struct intel_engine_cs *engine;
- bool mmio_flip;
- struct drm_i915_gem_request *request;
- struct i915_vma *vma;
- int ret;
-
- /*
- * drm_mode_page_flip_ioctl() should already catch this, but double
- * check to be safe. In the future we may enable pageflipping from
- * a disabled primary plane.
- */
- if (WARN_ON(intel_fb_obj(old_fb) == NULL))
- return -EBUSY;
-
- /* Can't change pixel format via MI display flips. */
- if (fb->format != crtc->primary->fb->format)
- return -EINVAL;
-
- /*
- * TILEOFF/LINOFF registers can't be changed via MI display flips.
- * Note that pitch changes could also affect these register.
- */
- if (INTEL_GEN(dev_priv) > 3 &&
- (fb->offsets[0] != crtc->primary->fb->offsets[0] ||
- fb->pitches[0] != crtc->primary->fb->pitches[0]))
- return -EINVAL;
-
- if (i915_terminally_wedged(&dev_priv->gpu_error))
- goto out_hang;
-
- work = kzalloc(sizeof(*work), GFP_KERNEL);
- if (work == NULL)
- return -ENOMEM;
-
- work->event = event;
- work->crtc = crtc;
- work->old_fb = old_fb;
- INIT_WORK(&work->unpin_work, intel_unpin_work_fn);
-
- ret = drm_crtc_vblank_get(crtc);
- if (ret)
- goto free_work;
-
- /* We borrow the event spin lock for protecting flip_work */
- spin_lock_irq(&dev->event_lock);
- if (intel_crtc->flip_work) {
- /* Before declaring the flip queue wedged, check if
- * the hardware completed the operation behind our backs.
- */
- if (pageflip_finished(intel_crtc, intel_crtc->flip_work)) {
- DRM_DEBUG_DRIVER("flip queue: previous flip completed, continuing\n");
- page_flip_completed(intel_crtc);
- } else {
- DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
- spin_unlock_irq(&dev->event_lock);
-
- drm_crtc_vblank_put(crtc);
- kfree(work);
- return -EBUSY;
- }
- }
- intel_crtc->flip_work = work;
- spin_unlock_irq(&dev->event_lock);
-
- if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
- flush_workqueue(dev_priv->wq);
-
- /* Reference the objects for the scheduled work. */
- drm_framebuffer_reference(work->old_fb);
-
- crtc->primary->fb = fb;
- update_state_fb(crtc->primary);
-
- work->pending_flip_obj = i915_gem_object_get(obj);
-
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- goto cleanup;
-
- intel_crtc->reset_count = i915_reset_count(&dev_priv->gpu_error);
- if (i915_reset_backoff_or_wedged(&dev_priv->gpu_error)) {
- ret = -EIO;
- goto unlock;
- }
-
- atomic_inc(&intel_crtc->unpin_work_count);
-
- if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
- work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
-
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- engine = dev_priv->engine[BCS];
- if (fb->modifier != old_fb->modifier)
- /* vlv: DISPLAY_FLIP fails to change tiling */
- engine = NULL;
- } else if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) {
- engine = dev_priv->engine[BCS];
- } else if (INTEL_GEN(dev_priv) >= 7) {
- engine = i915_gem_object_last_write_engine(obj);
- if (engine == NULL || engine->id != RCS)
- engine = dev_priv->engine[BCS];
- } else {
- engine = dev_priv->engine[RCS];
- }
-
- mmio_flip = use_mmio_flip(engine, obj);
-
- vma = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
- if (IS_ERR(vma)) {
- ret = PTR_ERR(vma);
- goto cleanup_pending;
- }
-
- work->old_vma = to_intel_plane_state(primary->state)->vma;
- to_intel_plane_state(primary->state)->vma = vma;
-
- work->gtt_offset = i915_ggtt_offset(vma) + intel_crtc->dspaddr_offset;
- work->rotation = crtc->primary->state->rotation;
-
- /*
- * There's the potential that the next frame will not be compatible with
- * FBC, so we want to call pre_update() before the actual page flip.
- * The problem is that pre_update() caches some information about the fb
- * object, so we want to do this only after the object is pinned. Let's
- * be on the safe side and do this immediately before scheduling the
- * flip.
- */
- intel_fbc_pre_update(intel_crtc, intel_crtc->config,
- to_intel_plane_state(primary->state));
-
- if (mmio_flip) {
- INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func);
- queue_work(system_unbound_wq, &work->mmio_work);
- } else {
- request = i915_gem_request_alloc(engine,
- dev_priv->kernel_context);
- if (IS_ERR(request)) {
- ret = PTR_ERR(request);
- goto cleanup_unpin;
- }
-
- ret = i915_gem_request_await_object(request, obj, false);
- if (ret)
- goto cleanup_request;
-
- ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
- page_flip_flags);
- if (ret)
- goto cleanup_request;
-
- intel_mark_page_flip_active(intel_crtc, work);
-
- work->flip_queued_req = i915_gem_request_get(request);
- i915_add_request(request);
- }
-
- i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
- i915_gem_track_fb(intel_fb_obj(old_fb), obj,
- to_intel_plane(primary)->frontbuffer_bit);
- mutex_unlock(&dev->struct_mutex);
-
- intel_frontbuffer_flip_prepare(to_i915(dev),
- to_intel_plane(primary)->frontbuffer_bit);
-
- trace_i915_flip_request(intel_crtc->plane, obj);
-
- return 0;
-
-cleanup_request:
- i915_add_request(request);
-cleanup_unpin:
- to_intel_plane_state(primary->state)->vma = work->old_vma;
- intel_unpin_fb_vma(vma);
-cleanup_pending:
- atomic_dec(&intel_crtc->unpin_work_count);
-unlock:
- mutex_unlock(&dev->struct_mutex);
-cleanup:
- crtc->primary->fb = old_fb;
- update_state_fb(crtc->primary);
-
- i915_gem_object_put(obj);
- drm_framebuffer_unreference(work->old_fb);
-
- spin_lock_irq(&dev->event_lock);
- intel_crtc->flip_work = NULL;
- spin_unlock_irq(&dev->event_lock);
-
- drm_crtc_vblank_put(crtc);
-free_work:
- kfree(work);
-
- if (ret == -EIO) {
- struct drm_atomic_state *state;
- struct drm_plane_state *plane_state;
-
-out_hang:
- state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
- state->acquire_ctx = dev->mode_config.acquire_ctx;
-
-retry:
- plane_state = drm_atomic_get_plane_state(state, primary);
- ret = PTR_ERR_OR_ZERO(plane_state);
- if (!ret) {
- drm_atomic_set_fb_for_plane(plane_state, fb);
-
- ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
- if (!ret)
- ret = drm_atomic_commit(state);
- }
-
- if (ret == -EDEADLK) {
- drm_modeset_backoff(state->acquire_ctx);
- drm_atomic_state_clear(state);
- goto retry;
- }
-
- drm_atomic_state_put(state);
-
- if (ret == 0 && event) {
- spin_lock_irq(&dev->event_lock);
- drm_crtc_send_vblank_event(crtc, event);
- spin_unlock_irq(&dev->event_lock);
- }
- }
- return ret;
-}
-
-
/**
* intel_wm_need_update - Check whether watermarks need updating
* @plane: drm plane
@@ -14718,34 +14090,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
dev_priv->display.update_crtcs = skl_update_crtcs;
else
dev_priv->display.update_crtcs = intel_update_crtcs;
-
- switch (INTEL_INFO(dev_priv)->gen) {
- case 2:
- dev_priv->display.queue_flip = intel_gen2_queue_flip;
- break;
-
- case 3:
- dev_priv->display.queue_flip = intel_gen3_queue_flip;
- break;
-
- case 4:
- case 5:
- dev_priv->display.queue_flip = intel_gen4_queue_flip;
- break;
-
- case 6:
- dev_priv->display.queue_flip = intel_gen6_queue_flip;
- break;
- case 7:
- case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
- dev_priv->display.queue_flip = intel_gen7_queue_flip;
- break;
- case 9:
- /* Drop through - unsupported since execlist only. */
- default:
- /* Default just returns -ENODEV to indicate unsupported */
- dev_priv->display.queue_flip = intel_default_queue_flip;
- }
}
/*
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/7] drm/i915: Unbreak gpu reset vs. modeset locking
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
2017-07-15 11:40 ` [PATCH 1/7] drm/i915: Nuke legacy flip queueing code Daniel Vetter
@ 2017-07-15 11:40 ` Daniel Vetter
2017-07-17 17:14 ` Maarten Lankhorst
2017-07-15 11:40 ` [PATCH 3/7] drm/atomic-helper: add sync_all helper for gpu reset Daniel Vetter
` (5 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:40 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Daniel Vetter
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.
Fixes: 739748939974 ("drm/i915: Fix modeset handling during gpu reset, v5.")
Cc: 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>
---
drivers/gpu/drm/i915/intel_display.c | 53 +++++++++---------------------------
1 file changed, 13 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f69333b8995c..e3c55a996f6b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3413,26 +3413,6 @@ static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
intel_finish_page_flip_cs(dev_priv, crtc->pipe);
}
-static void intel_update_primary_planes(struct drm_device *dev)
-{
- struct drm_crtc *crtc;
-
- for_each_crtc(dev, crtc) {
- struct intel_plane *plane = to_intel_plane(crtc->primary);
- struct intel_plane_state *plane_state =
- to_intel_plane_state(plane->base.state);
-
- if (plane_state->base.visible) {
- trace_intel_update_plane(&plane->base,
- to_intel_crtc(crtc));
-
- plane->update_plane(plane,
- to_intel_crtc_state(crtc->state),
- plane_state);
- }
- }
-}
-
static int
__intel_display_resume(struct drm_device *dev,
struct drm_atomic_state *state,
@@ -3485,6 +3465,12 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
struct drm_atomic_state *state;
int ret;
+
+ /* reset doesn't touch the display, but flips might get nuked anyway, */
+ if (!i915.force_reset_modeset_test &&
+ !gpu_reset_clobbers_display(dev_priv))
+ return;
+
/*
* Need mode_config.mutex so that we don't
* trample ongoing ->detect() and whatnot.
@@ -3498,12 +3484,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
drm_modeset_backoff(ctx);
}
-
- /* reset doesn't touch the display, but flips might get nuked anyway, */
- if (!i915.force_reset_modeset_test &&
- !gpu_reset_clobbers_display(dev_priv))
- return;
-
/*
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
@@ -3533,6 +3513,11 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
struct drm_atomic_state *state = dev_priv->modeset_restore_state;
int ret;
+ /* reset doesn't touch the display, but flips might get nuked anyway, */
+ if (!i915.force_reset_modeset_test &&
+ !gpu_reset_clobbers_display(dev_priv))
+ return;
+
/*
* Flips in the rings will be nuked by the reset,
* so complete all pending flips so that user space
@@ -3544,22 +3529,10 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
/* reset doesn't touch the display */
if (!gpu_reset_clobbers_display(dev_priv)) {
- 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, ctx);
+ /* for testing only restore the display */
+ ret = __intel_display_resume(dev, state, ctx);
if (ret)
DRM_ERROR("Restoring old state failed with %i\n", ret);
- }
} else {
/*
* The display has been reset as well,
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/7] drm/atomic-helper: add sync_all helper for gpu reset
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
2017-07-15 11:40 ` [PATCH 1/7] drm/i915: Nuke legacy flip queueing code Daniel Vetter
2017-07-15 11:40 ` [PATCH 2/7] drm/i915: Unbreak gpu reset vs. modeset locking Daniel Vetter
@ 2017-07-15 11:40 ` Daniel Vetter
2017-07-17 12:30 ` Mika Kuoppala
2017-07-15 11:40 ` [PATCH 4/7] drm/i915: only disable outputs in simulated gpu resets Daniel Vetter
` (4 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:40 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Daniel Vetter
i915 needs this.
Cc: 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>
---
drivers/gpu/drm/drm_atomic_helper.c | 38 +++++++++++++++++++++++++++++++++++++
include/drm/drm_atomic_helper.h | 1 +
2 files changed, 39 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index cea610161af5..545328a9a769 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1763,6 +1763,44 @@ static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
}
/**
+ * drm_atomic_helper_sync_all - synchronize with all pending nonblocking commits
+ * @dev: DRM device
+ *
+ * This function synchronizes with all pending atomic commits using the
+ * nonblocking helpers (see drm_atomic_helper_setup_commit()) up to the point
+ * where all hardware commits are completed (as signalled using
+ * drm_atomic_helper_commit_hw_done().
+ *
+ * This is useful you need to synchronize with all nonblocking comits, but do
+ * not want to or cannot do a full atomic commit touching all CRTC. All CRTC
+ * looks must be held to prevent a concurrent thread from queuing yet another
+ * update. Drivers can use this for e.g. their gpu reset handling, when a gpu
+ * reset also affects the display block.
+ */
+void drm_atomic_helper_sync_all(struct drm_device *dev)
+{
+ struct drm_crtc *crtc;
+ struct drm_crtc_commit *commit;
+
+ drm_for_each_crtc(crtc, dev) {
+ spin_lock(&crtc->commit_lock);
+ commit = list_first_entry_or_null(&crtc->commit_list,
+ struct drm_crtc_commit, commit_entry);
+ if (commit)
+ drm_crtc_commit_get(commit);
+ spin_unlock(&crtc->commit_lock);
+
+ if (!commit)
+ continue;
+
+ wait_for_completion(&commit->hw_done);
+
+ drm_crtc_commit_put(commit);
+ }
+}
+EXPORT_SYMBOL(drm_atomic_helper_sync_all);
+
+/**
* drm_atomic_helper_wait_for_dependencies - wait for required preceeding commits
* @old_state: atomic state object with old state structures
*
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index ed90d0c5ba09..95bef7c3632f 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -92,6 +92,7 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
/* nonblocking commit helpers */
int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
bool nonblock);
+void drm_atomic_helper_sync_all(struct drm_device *dev);
void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/7] drm/i915: only disable outputs in simulated gpu resets
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
` (2 preceding siblings ...)
2017-07-15 11:40 ` [PATCH 3/7] drm/atomic-helper: add sync_all helper for gpu reset Daniel Vetter
@ 2017-07-15 11:40 ` Daniel Vetter
2017-07-15 11:40 ` [PATCH 5/7] drm/i915: Avoid the gpu reset vs. modeset deadlock Daniel Vetter
` (3 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:40 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Daniel Vetter
For the old chips where the reset also kills the display we don't need
to do this, it all goes down on its own. We only need to do this for
gpu resets where the interaction with the display side is simulated.
This means we're not 100% faithful with what we test, but there's a
big pile of other small differences (like having to restore interrupts
and hpd handling and everything else).
Doing that means we don't have a full commit to synchronize with all
outstanding changes, so use the new helper to do that instead.
Cc: 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>
---
drivers/gpu/drm/i915/intel_display.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e3c55a996f6b..b0de36f11f6d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3484,6 +3484,8 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
drm_modeset_backoff(ctx);
}
+ drm_atomic_helper_sync_all(dev);
+
/*
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
@@ -3495,11 +3497,15 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
return;
}
- ret = drm_atomic_helper_disable_all(dev, ctx);
- if (ret) {
- DRM_ERROR("Suspending crtc's failed with %i\n", ret);
- drm_atomic_state_put(state);
- return;
+ /* only when we test this through force_reset_modeset_test shut down the
+ * entire display manually. For hw where gpu reset kills the display
+ * this happens automatically. This avoids unecessary trouble with
+ * double-commit.
+ */
+ if (!gpu_reset_clobbers_display(dev_priv)) {
+ ret = drm_atomic_helper_disable_all(dev, ctx);
+ if (ret)
+ DRM_ERROR("Suspending crtc's failed with %i\n", ret);
}
dev_priv->modeset_restore_state = state;
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/7] drm/i915: Avoid the gpu reset vs. modeset deadlock
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
` (3 preceding siblings ...)
2017-07-15 11:40 ` [PATCH 4/7] drm/i915: only disable outputs in simulated gpu resets Daniel Vetter
@ 2017-07-15 11:40 ` Daniel Vetter
2017-07-15 11:40 ` [PATCH 6/7] drm/i915: Push i915_sw_fence_wait into the nonblocking atomic commit Daniel Vetter
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:40 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Mika Kuoppala, Daniel Vetter
... using the biggest hammer we have. This is essentially a weaponized
version of the timeout-based wedging Chris added in
commit 36703e79a982c8ce5a8e43833291f2719e92d0d1
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Thu Jun 22 11:56:25 2017 +0100
drm/i915: Break modeset deadlocks on reset
Because defense-in-depth is good it's good to still have both. Also
note that with the locking change we can now restrict this a lot (old
gpus and special testing only), so this doesn't kill the TDR benefits
on at least anything remotely modern.
And futuremore with a few tricks it should be possible to make a much
more educated guess about whether an atomic commit is stuck waiting on
the gpu (atomic_t counting the pending i915_sw_fence used by the
atomic modeset code should do it), so we can improve this.
But for now just start with something that is guaranteed to recover
faster, for much better CI througput.
This defacto reverts TDR on these platforms, but there's not really a
single commit to specify as the sole offender.
Fixes: 4680816be336 ("drm/i915: Wait first for submission, before waiting for request completion")
Fixes: 221fe7994554 ("drm/i915: Perform a direct reset of the GPU from the waiter")
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b0de36f11f6d..dd541fe71d0a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3471,6 +3471,11 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
!gpu_reset_clobbers_display(dev_priv))
return;
+ /* We have a modeset vs reset deadlock, defensively unbreak it.
+ *
+ * FIXME: We can do a _lot_ better, this is just a first iteration.*/
+ i915_gem_set_wedged(dev_priv);
+
/*
* Need mode_config.mutex so that we don't
* trample ongoing ->detect() and whatnot.
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/7] drm/i915: Push i915_sw_fence_wait into the nonblocking atomic commit
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
` (4 preceding siblings ...)
2017-07-15 11:40 ` [PATCH 5/7] drm/i915: Avoid the gpu reset vs. modeset deadlock Daniel Vetter
@ 2017-07-15 11:40 ` Daniel Vetter
2017-07-15 11:40 ` [PATCH 7/7] drm/i915: More surgically unbreak the modeset vs reset deadlock Daniel Vetter
2017-07-15 12:00 ` ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock Patchwork
7 siblings, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:40 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Mika Kuoppala, Daniel Vetter
Blocking in a worker is ok, that's what the unbound_wq is for. And it
unifies the paths between the blocking and nonblocking commit, giving
me just one path where I have to implement the deadlock avoidance
trickery in the next patch.
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index dd541fe71d0a..f2ceb908ee95 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12390,6 +12390,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
unsigned crtc_vblank_mask = 0;
int i;
+ i915_sw_fence_wait(&intel_state->commit_ready);
+
drm_atomic_helper_wait_for_dependencies(state);
if (intel_state->modeset)
@@ -12557,10 +12559,7 @@ intel_atomic_commit_ready(struct i915_sw_fence *fence,
switch (notify) {
case FENCE_COMPLETE:
- if (state->base.commit_work.func)
- queue_work(system_unbound_wq, &state->base.commit_work);
break;
-
case FENCE_FREE:
{
struct intel_atomic_helper *helper =
@@ -12656,14 +12655,14 @@ static int intel_atomic_commit(struct drm_device *dev,
}
drm_atomic_state_get(state);
- INIT_WORK(&state->commit_work,
- nonblock ? intel_atomic_commit_work : NULL);
+ INIT_WORK(&state->commit_work, intel_atomic_commit_work);
i915_sw_fence_commit(&intel_state->commit_ready);
- if (!nonblock) {
- i915_sw_fence_wait(&intel_state->commit_ready);
+ if (nonblock)
+ queue_work(system_unbound_wq, &state->commit_work);
+ else
intel_atomic_commit_tail(state);
- }
+
return 0;
}
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 7/7] drm/i915: More surgically unbreak the modeset vs reset deadlock
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
` (5 preceding siblings ...)
2017-07-15 11:40 ` [PATCH 6/7] drm/i915: Push i915_sw_fence_wait into the nonblocking atomic commit Daniel Vetter
@ 2017-07-15 11:40 ` Daniel Vetter
2017-07-15 12:00 ` ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock Patchwork
7 siblings, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 11:40 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Mika Kuoppala, Daniel Vetter
There's no reason to entirely wedge the gpu, for the minimal deadlock
bugfix we only need to unbreak/decouple the atomic commit from the gpu
reset. The simplest wait to fix that is by replacing the
unconditional fence wait a the top of commit_tail by a wait which
completes either when the fences are done (normal case, or when a
reset doesn't need to touch the display state). Or when the gpu reset
needs to force-unblock all pending modeset states.
Note that in both cases TDR itself keeps working, so from a userspace
pov this trickery isn't observable. Users themselvs might spot a short
glitch while the rendering is catching up again, but that's still
better than pre-TDR where we've thrown away all the rendering,
including innocent batches. Also, this fixes the regression TDR
introduced of making gpu resets deadlock-prone when we do need to
touch the display.
One thing I noticed is that gpu_error.flags seems to use both our own
wait-queue in gpu_error.wait_queue, and the generic wait_on_bit
facilities. Not entirely sure why this inconsistency exists, I just
picked one style.
A possible future avenue could be to insert the gpu reset in-between
ongoing modeset changes, which would avoid the momentary glitch. But
that's a lot more work to implement in the atomic commit machinery,
and given that we only need this for pre-g4x hw, of questionable
utility just for the sake of polishing gpu reset even more on those
old boxes. It might be useful for other features though.
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 35 ++++++++++++++++++++++++++++++-----
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bdee66ca23af..ac64ac628bfb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1564,6 +1564,7 @@ struct i915_gpu_error {
unsigned long flags;
#define I915_RESET_BACKOFF 0
#define I915_RESET_HANDOFF 1
+#define I915_RESET_MODESET 2
#define I915_WEDGED (BITS_PER_LONG - 1)
#define I915_RESET_ENGINE (I915_WEDGED - I915_NUM_ENGINES)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f2ceb908ee95..9524d6d769e4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3471,10 +3471,9 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
!gpu_reset_clobbers_display(dev_priv))
return;
- /* We have a modeset vs reset deadlock, defensively unbreak it.
- *
- * FIXME: We can do a _lot_ better, this is just a first iteration.*/
- i915_gem_set_wedged(dev_priv);
+ /* We have a modeset vs reset deadlock, defensively unbreak it. */
+ set_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
+ wake_up_all(&dev_priv->gpu_error.wait_queue);
/*
* Need mode_config.mutex so that we don't
@@ -3572,6 +3571,8 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);
mutex_unlock(&dev->mode_config.mutex);
+
+ clear_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
}
static bool abort_flip_on_reset(struct intel_crtc *crtc)
@@ -12377,6 +12378,30 @@ static void intel_atomic_helper_free_state_worker(struct work_struct *work)
intel_atomic_helper_free_state(dev_priv);
}
+static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state)
+{
+ wait_queue_t wait_fence, wait_reset;
+ struct drm_i915_private *dev_priv = to_i915(intel_state->base.dev);
+
+ init_wait_entry(&wait_fence, 0);
+ init_wait_entry(&wait_reset, 0);
+ for (;;) {
+ prepare_to_wait(&intel_state->commit_ready.wait,
+ &wait_fence, TASK_UNINTERRUPTIBLE);
+ prepare_to_wait(&dev_priv->gpu_error.wait_queue,
+ &wait_reset, TASK_UNINTERRUPTIBLE);
+
+
+ if (i915_sw_fence_done(&intel_state->commit_ready)
+ || (dev_priv->gpu_error.flags & I915_RESET_MODESET))
+ break;
+
+ schedule();
+ }
+ finish_wait(&intel_state->commit_ready.wait, &wait_fence);
+ finish_wait(&dev_priv->gpu_error.wait_queue, &wait_reset);
+}
+
static void intel_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
@@ -12390,7 +12415,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
unsigned crtc_vblank_mask = 0;
int i;
- i915_sw_fence_wait(&intel_state->commit_ready);
+ intel_atomic_commit_fence_wait(intel_state);
drm_atomic_helper_wait_for_dependencies(state);
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 14+ messages in thread
* ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
` (6 preceding siblings ...)
2017-07-15 11:40 ` [PATCH 7/7] drm/i915: More surgically unbreak the modeset vs reset deadlock Daniel Vetter
@ 2017-07-15 12:00 ` Patchwork
2017-07-15 13:23 ` Daniel Vetter
7 siblings, 1 reply; 14+ messages in thread
From: Patchwork @ 2017-07-15 12:00 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
== Series Details ==
Series: RFC: duct-tape for the gpu reset vs. modeset deadlock
URL : https://patchwork.freedesktop.org/series/27345/
State : warning
== Summary ==
Series 27345v1 RFC: duct-tape for the gpu reset vs. modeset deadlock
https://patchwork.freedesktop.org/api/1.0/series/27345/revisions/1/mbox/
Test drv_hangman:
Subgroup error-state-basic:
pass -> DMESG-WARN (fi-blb-e6850)
pass -> DMESG-WARN (fi-pnv-d510)
Test gem_busy:
Subgroup basic-hang-default:
pass -> DMESG-WARN (fi-blb-e6850)
pass -> DMESG-WARN (fi-pnv-d510)
Test gem_exec_fence:
Subgroup await-hang-default:
pass -> DMESG-WARN (fi-blb-e6850)
pass -> DMESG-WARN (fi-pnv-d510)
Test gem_exec_flush:
Subgroup basic-batch-kernel-default-uc:
fail -> PASS (fi-snb-2600) fdo#100007
Test kms_pipe_crc_basic:
Subgroup hang-read-crc-pipe-a:
pass -> DMESG-WARN (fi-pnv-d510) fdo#101597
Subgroup suspend-read-crc-pipe-b:
pass -> DMESG-WARN (fi-byt-j1900) fdo#101705
fdo#100007 https://bugs.freedesktop.org/show_bug.cgi?id=100007
fdo#101597 https://bugs.freedesktop.org/show_bug.cgi?id=101597
fdo#101705 https://bugs.freedesktop.org/show_bug.cgi?id=101705
fi-bdw-5557u total:279 pass:268 dwarn:0 dfail:0 fail:0 skip:11 time:437s
fi-bdw-gvtdvm total:279 pass:265 dwarn:0 dfail:0 fail:0 skip:14 time:429s
fi-blb-e6850 total:279 pass:221 dwarn:4 dfail:0 fail:0 skip:54 time:354s
fi-bsw-n3050 total:279 pass:243 dwarn:0 dfail:0 fail:0 skip:36 time:531s
fi-bxt-j4205 total:279 pass:260 dwarn:0 dfail:0 fail:0 skip:19 time:518s
fi-byt-j1900 total:279 pass:254 dwarn:1 dfail:0 fail:0 skip:24 time:493s
fi-byt-n2820 total:279 pass:250 dwarn:1 dfail:0 fail:0 skip:28 time:479s
fi-glk-2a total:279 pass:260 dwarn:0 dfail:0 fail:0 skip:19 time:601s
fi-hsw-4770 total:279 pass:263 dwarn:0 dfail:0 fail:0 skip:16 time:435s
fi-hsw-4770r total:279 pass:263 dwarn:0 dfail:0 fail:0 skip:16 time:411s
fi-ilk-650 total:279 pass:229 dwarn:0 dfail:0 fail:0 skip:50 time:421s
fi-ivb-3520m total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:499s
fi-ivb-3770 total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:475s
fi-kbl-7500u total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:471s
fi-kbl-7560u total:279 pass:269 dwarn:0 dfail:0 fail:0 skip:10 time:577s
fi-kbl-r total:279 pass:260 dwarn:1 dfail:0 fail:0 skip:18 time:584s
fi-pnv-d510 total:279 pass:219 dwarn:5 dfail:0 fail:0 skip:55 time:564s
fi-skl-6260u total:279 pass:269 dwarn:0 dfail:0 fail:0 skip:10 time:464s
fi-skl-6700hq total:279 pass:262 dwarn:0 dfail:0 fail:0 skip:17 time:586s
fi-skl-6700k total:279 pass:257 dwarn:4 dfail:0 fail:0 skip:18 time:475s
fi-skl-6770hq total:279 pass:269 dwarn:0 dfail:0 fail:0 skip:10 time:484s
fi-skl-gvtdvm total:279 pass:266 dwarn:0 dfail:0 fail:0 skip:13 time:432s
fi-skl-x1585l total:279 pass:268 dwarn:0 dfail:0 fail:0 skip:11 time:474s
fi-snb-2520m total:279 pass:251 dwarn:0 dfail:0 fail:0 skip:28 time:546s
fi-snb-2600 total:279 pass:250 dwarn:0 dfail:0 fail:0 skip:29 time:403s
bd5641a8649223257233c4e1c45fc94abec1cdbe drm-tip: 2017y-07m-14d-19h-18m-56s UTC integration manifest
a9fddee drm/i915: More surgically unbreak the modeset vs reset deadlock
9bf2209 drm/i915: Push i915_sw_fence_wait into the nonblocking atomic commit
4c27139 drm/i915: Avoid the gpu reset vs. modeset deadlock
1bd5c02 drm/i915: only disable outputs in simulated gpu resets
ad9cbab drm/atomic-helper: add sync_all helper for gpu reset
8e0c068 drm/i915: Unbreak gpu reset vs. modeset locking
78406cd drm/i915: Nuke legacy flip queueing code
== Logs ==
For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_5202/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock
2017-07-15 12:00 ` ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock Patchwork
@ 2017-07-15 13:23 ` Daniel Vetter
2017-07-15 13:45 ` Daniel Vetter
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 13:23 UTC (permalink / raw)
To: intel-gfx
On Sat, Jul 15, 2017 at 2:00 PM, Patchwork
<patchwork@emeril.freedesktop.org> wrote:
> == Series Details ==
>
> Series: RFC: duct-tape for the gpu reset vs. modeset deadlock
> URL : https://patchwork.freedesktop.org/series/27345/
> State : warning
>
> == Summary ==
>
> Series 27345v1 RFC: duct-tape for the gpu reset vs. modeset deadlock
> https://patchwork.freedesktop.org/api/1.0/series/27345/revisions/1/mbox/
>
> Test drv_hangman:
> Subgroup error-state-basic:
> pass -> DMESG-WARN (fi-blb-e6850)
> pass -> DMESG-WARN (fi-pnv-d510)
> Test gem_busy:
> Subgroup basic-hang-default:
> pass -> DMESG-WARN (fi-blb-e6850)
> pass -> DMESG-WARN (fi-pnv-d510)
> Test gem_exec_fence:
> Subgroup await-hang-default:
> pass -> DMESG-WARN (fi-blb-e6850)
> pass -> DMESG-WARN (fi-pnv-d510)
Looks like I wreaked something on gpus where the hw reset kills the
display. I'll check it out.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - 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] 14+ messages in thread
* Re: ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock
2017-07-15 13:23 ` Daniel Vetter
@ 2017-07-15 13:45 ` Daniel Vetter
2017-07-17 10:01 ` Maarten Lankhorst
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Vetter @ 2017-07-15 13:45 UTC (permalink / raw)
To: intel-gfx
On Sat, Jul 15, 2017 at 3:23 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> On Sat, Jul 15, 2017 at 2:00 PM, Patchwork
> <patchwork@emeril.freedesktop.org> wrote:
>> == Series Details ==
>>
>> Series: RFC: duct-tape for the gpu reset vs. modeset deadlock
>> URL : https://patchwork.freedesktop.org/series/27345/
>> State : warning
>>
>> == Summary ==
>>
>> Series 27345v1 RFC: duct-tape for the gpu reset vs. modeset deadlock
>> https://patchwork.freedesktop.org/api/1.0/series/27345/revisions/1/mbox/
>>
>> Test drv_hangman:
>> Subgroup error-state-basic:
>> pass -> DMESG-WARN (fi-blb-e6850)
>> pass -> DMESG-WARN (fi-pnv-d510)
>> Test gem_busy:
>> Subgroup basic-hang-default:
>> pass -> DMESG-WARN (fi-blb-e6850)
>> pass -> DMESG-WARN (fi-pnv-d510)
>> Test gem_exec_fence:
>> Subgroup await-hang-default:
>> pass -> DMESG-WARN (fi-blb-e6850)
>> pass -> DMESG-WARN (fi-pnv-d510)
>
> Looks like I wreaked something on gpus where the hw reset kills the
> display. I'll check it out.
Ok, simplest solution seems to be to just not do the special casing
between real hw reset and fake reset, and unconditionally shut down
all the CRTC. Probably a lot more than just the power domain tracking
will get out of whack. I wasn't really sold on that idea either way,
so I'll drop both "drm/i915: only disable outputs in simulated gpu
resets" and "drm/atomic-helper: add sync_all helper for gpu reset"
from the series. They're not needed really anyway.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - 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] 14+ messages in thread
* Re: ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock
2017-07-15 13:45 ` Daniel Vetter
@ 2017-07-17 10:01 ` Maarten Lankhorst
0 siblings, 0 replies; 14+ messages in thread
From: Maarten Lankhorst @ 2017-07-17 10:01 UTC (permalink / raw)
To: Daniel Vetter, intel-gfx
Op 15-07-17 om 15:45 schreef Daniel Vetter:
> On Sat, Jul 15, 2017 at 3:23 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>> On Sat, Jul 15, 2017 at 2:00 PM, Patchwork
>> <patchwork@emeril.freedesktop.org> wrote:
>>> == Series Details ==
>>>
>>> Series: RFC: duct-tape for the gpu reset vs. modeset deadlock
>>> URL : https://patchwork.freedesktop.org/series/27345/
>>> State : warning
>>>
>>> == Summary ==
>>>
>>> Series 27345v1 RFC: duct-tape for the gpu reset vs. modeset deadlock
>>> https://patchwork.freedesktop.org/api/1.0/series/27345/revisions/1/mbox/
>>>
>>> Test drv_hangman:
>>> Subgroup error-state-basic:
>>> pass -> DMESG-WARN (fi-blb-e6850)
>>> pass -> DMESG-WARN (fi-pnv-d510)
>>> Test gem_busy:
>>> Subgroup basic-hang-default:
>>> pass -> DMESG-WARN (fi-blb-e6850)
>>> pass -> DMESG-WARN (fi-pnv-d510)
>>> Test gem_exec_fence:
>>> Subgroup await-hang-default:
>>> pass -> DMESG-WARN (fi-blb-e6850)
>>> pass -> DMESG-WARN (fi-pnv-d510)
>> Looks like I wreaked something on gpus where the hw reset kills the
>> display. I'll check it out.
> Ok, simplest solution seems to be to just not do the special casing
> between real hw reset and fake reset, and unconditionally shut down
> all the CRTC. Probably a lot more than just the power domain tracking
> will get out of whack. I wasn't really sold on that idea either way,
> so I'll drop both "drm/i915: only disable outputs in simulated gpu
> resets" and "drm/atomic-helper: add sync_all helper for gpu reset"
> from the series. They're not needed really anyway.
> -Daniel
Agreed, sync_all helper should have been done by the disable_all call.
The thing I didn't like was that you didn't shut down the GPU unconditionally, but with that fixed series looks good. :)
I like patch 6/7, it makes everything more clear.
I'm not sure if calling prepare_to_wait twice is allowed, but don't see why not.
So with those taken out and feedback addressed.
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/7] drm/atomic-helper: add sync_all helper for gpu reset
2017-07-15 11:40 ` [PATCH 3/7] drm/atomic-helper: add sync_all helper for gpu reset Daniel Vetter
@ 2017-07-17 12:30 ` Mika Kuoppala
0 siblings, 0 replies; 14+ messages in thread
From: Mika Kuoppala @ 2017-07-17 12:30 UTC (permalink / raw)
To: Intel Graphics Development; +Cc: Daniel Vetter, Daniel Vetter
Daniel Vetter <daniel.vetter@ffwll.ch> writes:
> i915 needs this.
>
> Cc: 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>
> ---
> drivers/gpu/drm/drm_atomic_helper.c | 38 +++++++++++++++++++++++++++++++++++++
> include/drm/drm_atomic_helper.h | 1 +
> 2 files changed, 39 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index cea610161af5..545328a9a769 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -1763,6 +1763,44 @@ static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
> }
>
> /**
> + * drm_atomic_helper_sync_all - synchronize with all pending nonblocking commits
> + * @dev: DRM device
> + *
> + * This function synchronizes with all pending atomic commits using the
> + * nonblocking helpers (see drm_atomic_helper_setup_commit()) up to the point
> + * where all hardware commits are completed (as signalled using
> + * drm_atomic_helper_commit_hw_done().
> + *
> + * This is useful you need to synchronize with all nonblocking comits, but do
s/comits/commits
> + * not want to or cannot do a full atomic commit touching all CRTC. All CRTC
> + * looks must be held to prevent a concurrent thread from queuing yet another
s/looks/locks
> + * update. Drivers can use this for e.g. their gpu reset handling, when a gpu
> + * reset also affects the display block.
> + */
> +void drm_atomic_helper_sync_all(struct drm_device *dev)
> +{
> + struct drm_crtc *crtc;
> + struct drm_crtc_commit *commit;
> +
> + drm_for_each_crtc(crtc, dev) {
> + spin_lock(&crtc->commit_lock);
> + commit = list_first_entry_or_null(&crtc->commit_list,
> + struct drm_crtc_commit, commit_entry);
> + if (commit)
> + drm_crtc_commit_get(commit);
> + spin_unlock(&crtc->commit_lock);
> +
> + if (!commit)
> + continue;
> +
> + wait_for_completion(&commit->hw_done);
> +
> + drm_crtc_commit_put(commit);
> + }
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_sync_all);
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
> +
> +/**
> * drm_atomic_helper_wait_for_dependencies - wait for required preceeding commits
> * @old_state: atomic state object with old state structures
> *
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index ed90d0c5ba09..95bef7c3632f 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -92,6 +92,7 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> /* nonblocking commit helpers */
> int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
> bool nonblock);
> +void drm_atomic_helper_sync_all(struct drm_device *dev);
> void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
> void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
> void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
> --
> 2.13.2
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/7] drm/i915: Unbreak gpu reset vs. modeset locking
2017-07-15 11:40 ` [PATCH 2/7] drm/i915: Unbreak gpu reset vs. modeset locking Daniel Vetter
@ 2017-07-17 17:14 ` Maarten Lankhorst
0 siblings, 0 replies; 14+ messages in thread
From: Maarten Lankhorst @ 2017-07-17 17:14 UTC (permalink / raw)
To: Daniel Vetter, Intel Graphics Development; +Cc: Daniel Vetter
Op 15-07-17 om 13:40 schreef Daniel Vetter:
> 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.
>
> Fixes: 739748939974 ("drm/i915: Fix modeset handling during gpu reset, v5.")
> Cc: 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>
> ---
> drivers/gpu/drm/i915/intel_display.c | 53 +++++++++---------------------------
> 1 file changed, 13 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index f69333b8995c..e3c55a996f6b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3413,26 +3413,6 @@ static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
> intel_finish_page_flip_cs(dev_priv, crtc->pipe);
> }
>
> -static void intel_update_primary_planes(struct drm_device *dev)
> -{
> - struct drm_crtc *crtc;
> -
> - for_each_crtc(dev, crtc) {
> - struct intel_plane *plane = to_intel_plane(crtc->primary);
> - struct intel_plane_state *plane_state =
> - to_intel_plane_state(plane->base.state);
> -
> - if (plane_state->base.visible) {
> - trace_intel_update_plane(&plane->base,
> - to_intel_crtc(crtc));
> -
> - plane->update_plane(plane,
> - to_intel_crtc_state(crtc->state),
> - plane_state);
> - }
> - }
> -}
> -
> static int
> __intel_display_resume(struct drm_device *dev,
> struct drm_atomic_state *state,
> @@ -3485,6 +3465,12 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
> struct drm_atomic_state *state;
> int ret;
>
> +
> + /* reset doesn't touch the display, but flips might get nuked anyway, */
I think this comment was meant to address the reasoning for taking all locks,
so the part about flips being nuked no longer applies with mmio flips gone.
> + if (!i915.force_reset_modeset_test &&
> + !gpu_reset_clobbers_display(dev_priv))
> + return;
> +
> /*
> * Need mode_config.mutex so that we don't
> * trample ongoing ->detect() and whatnot.
> @@ -3498,12 +3484,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
>
> drm_modeset_backoff(ctx);
> }
> -
> - /* reset doesn't touch the display, but flips might get nuked anyway, */
> - if (!i915.force_reset_modeset_test &&
> - !gpu_reset_clobbers_display(dev_priv))
> - return;
> -
> /*
> * Disabling the crtcs gracefully seems nicer. Also the
> * g33 docs say we should at least disable all the planes.
> @@ -3533,6 +3513,11 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
> struct drm_atomic_state *state = dev_priv->modeset_restore_state;
> int ret;
>
> + /* reset doesn't touch the display, but flips might get nuked anyway, */
> + if (!i915.force_reset_modeset_test &&
> + !gpu_reset_clobbers_display(dev_priv))
> + return;
Same thing about comment here. Perhaps change the
if (!i915.force_reset_modeset_test && !gpu_reset_clobbers_display())
to
if (!state && !gpu_reset_clobbers_display())
so we don't run into a kernel panic if we change the parameter during reset?
Hm perhaps also either add if (state) to the __intel_display_resume call for <g4x,
or remove the one for drm_atomic_state_put.
With those changes I'm happy, and you can add
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2017-07-17 17:14 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-15 11:39 [PATCH 0/7] RFC: duct-tape for the gpu reset vs. modeset deadlock Daniel Vetter
2017-07-15 11:40 ` [PATCH 1/7] drm/i915: Nuke legacy flip queueing code Daniel Vetter
2017-07-15 11:40 ` [PATCH 2/7] drm/i915: Unbreak gpu reset vs. modeset locking Daniel Vetter
2017-07-17 17:14 ` Maarten Lankhorst
2017-07-15 11:40 ` [PATCH 3/7] drm/atomic-helper: add sync_all helper for gpu reset Daniel Vetter
2017-07-17 12:30 ` Mika Kuoppala
2017-07-15 11:40 ` [PATCH 4/7] drm/i915: only disable outputs in simulated gpu resets Daniel Vetter
2017-07-15 11:40 ` [PATCH 5/7] drm/i915: Avoid the gpu reset vs. modeset deadlock Daniel Vetter
2017-07-15 11:40 ` [PATCH 6/7] drm/i915: Push i915_sw_fence_wait into the nonblocking atomic commit Daniel Vetter
2017-07-15 11:40 ` [PATCH 7/7] drm/i915: More surgically unbreak the modeset vs reset deadlock Daniel Vetter
2017-07-15 12:00 ` ✗ Fi.CI.BAT: warning for RFC: duct-tape for the gpu reset vs. modeset deadlock Patchwork
2017-07-15 13:23 ` Daniel Vetter
2017-07-15 13:45 ` Daniel Vetter
2017-07-17 10:01 ` Maarten Lankhorst
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox