* [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update @ 2015-09-10 15:34 Jesse Barnes 2015-09-10 15:34 ` [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail Jesse Barnes ` (2 more replies) 0 siblings, 3 replies; 23+ messages in thread From: Jesse Barnes @ 2015-09-10 15:34 UTC (permalink / raw) To: intel-gfx On HSW at least (still testing other platforms, but should be harmless elsewhere), the DSL reg reads back as 0 when read around vblank start time. This ends up confusing the atomic start/end checking code, since it causes the update to appear as if it crossed a frame count boundary. Workaround that by avoiding updates in the first couple of scanlines. In testing, even a delay of a single microsecond is enough to give us a good DSL value again, so the millisecond we'll wait when we hit this case occasionally ought to be plenty. References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> --- drivers/gpu/drm/i915/intel_sprite.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index ca7e264..0c2c62f 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -113,8 +113,16 @@ void intel_pipe_update_start(struct intel_crtc *crtc) */ prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); + /* + * On HSW, the DSL reg (0x70000) appears to return 0 if we + * read it right around the start of vblank. So skip past it + * so we don't accidentally end up spanning a vblank frame + * increment, causing the update_end() code to squak at us. + * (We use 2 in the comparison to account for the + * scanline_offset used to correct the DSL readout.) + */ scanline = intel_get_crtc_scanline(crtc); - if (scanline < min || scanline > max) + if (scanline > 2 && (scanline < min || scanline > max)) break; if (timeout <= 0) { -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail 2015-09-10 15:34 [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Jesse Barnes @ 2015-09-10 15:34 ` Jesse Barnes 2015-09-10 16:05 ` Ville Syrjälä 2015-09-15 17:03 ` [PATCH] drm/i915: add more debug info for when atomic updates fail v2 Jesse Barnes 2015-09-10 16:11 ` [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Ville Syrjälä 2015-09-10 21:38 ` [PATCH] drm/i915: workaround bad DSL readout v2 Jesse Barnes 2 siblings, 2 replies; 23+ messages in thread From: Jesse Barnes @ 2015-09-10 15:34 UTC (permalink / raw) To: intel-gfx I used these additional fields to track down the issue I saw on HSW. References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> --- drivers/gpu/drm/i915/intel_drv.h | 2 ++ drivers/gpu/drm/i915/intel_sprite.c | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 46484e4..90cad50 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -565,6 +565,8 @@ struct intel_crtc { unsigned start_vbl_count; ktime_t start_vbl_time; + int min_vbl, max_vbl; + int scanline_start; struct intel_crtc_atomic_commit atomic; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 0c2c62f..ff8c9d5 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -94,6 +94,9 @@ void intel_pipe_update_start(struct intel_crtc *crtc) min = vblank_start - usecs_to_scanlines(mode, 100); max = vblank_start - 1; + crtc->min_vbl = min; + crtc->max_vbl = max; + local_irq_disable(); crtc->start_vbl_count = 0; @@ -122,8 +125,10 @@ void intel_pipe_update_start(struct intel_crtc *crtc) * scanline_offset used to correct the DSL readout.) */ scanline = intel_get_crtc_scanline(crtc); - if (scanline > 2 && (scanline < min || scanline > max)) + if (scanline > 2 && (scanline < min || scanline > max)) { + crtc->scanline_start = scanline; break; + } if (timeout <= 0) { DRM_ERROR("Potential atomic update failure on pipe %c\n", @@ -169,10 +174,13 @@ void intel_pipe_update_end(struct intel_crtc *crtc) local_irq_enable(); - if (crtc->start_vbl_count && crtc->start_vbl_count != end_vbl_count) - DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us\n", + if (crtc->start_vbl_count && crtc->start_vbl_count != end_vbl_count) { + DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", pipe_name(pipe), crtc->start_vbl_count, end_vbl_count, - ktime_us_delta(end_vbl_time, crtc->start_vbl_time)); + ktime_us_delta(end_vbl_time, crtc->start_vbl_time), + crtc->min_vbl, crtc->max_vbl, crtc->scanline_start, + intel_get_crtc_scanline(crtc)); + } } static void -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail 2015-09-10 15:34 ` [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail Jesse Barnes @ 2015-09-10 16:05 ` Ville Syrjälä 2015-09-10 16:14 ` Jesse Barnes 2015-09-10 20:23 ` Jesse Barnes 2015-09-15 17:03 ` [PATCH] drm/i915: add more debug info for when atomic updates fail v2 Jesse Barnes 1 sibling, 2 replies; 23+ messages in thread From: Ville Syrjälä @ 2015-09-10 16:05 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 08:34:23AM -0700, Jesse Barnes wrote: > I used these additional fields to track down the issue I saw on HSW. We already have the tracepoints with the scanline information. Not sure what extra this would give. > > References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > drivers/gpu/drm/i915/intel_drv.h | 2 ++ > drivers/gpu/drm/i915/intel_sprite.c | 16 ++++++++++++---- > 2 files changed, 14 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 46484e4..90cad50 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -565,6 +565,8 @@ struct intel_crtc { > > unsigned start_vbl_count; > ktime_t start_vbl_time; > + int min_vbl, max_vbl; > + int scanline_start; > > struct intel_crtc_atomic_commit atomic; > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c > index 0c2c62f..ff8c9d5 100644 > --- a/drivers/gpu/drm/i915/intel_sprite.c > +++ b/drivers/gpu/drm/i915/intel_sprite.c > @@ -94,6 +94,9 @@ void intel_pipe_update_start(struct intel_crtc *crtc) > min = vblank_start - usecs_to_scanlines(mode, 100); > max = vblank_start - 1; > > + crtc->min_vbl = min; > + crtc->max_vbl = max; > + > local_irq_disable(); > crtc->start_vbl_count = 0; > > @@ -122,8 +125,10 @@ void intel_pipe_update_start(struct intel_crtc *crtc) > * scanline_offset used to correct the DSL readout.) > */ > scanline = intel_get_crtc_scanline(crtc); > - if (scanline > 2 && (scanline < min || scanline > max)) > + if (scanline > 2 && (scanline < min || scanline > max)) { > + crtc->scanline_start = scanline; > break; > + } > > if (timeout <= 0) { > DRM_ERROR("Potential atomic update failure on pipe %c\n", > @@ -169,10 +174,13 @@ void intel_pipe_update_end(struct intel_crtc *crtc) > > local_irq_enable(); > > - if (crtc->start_vbl_count && crtc->start_vbl_count != end_vbl_count) > - DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us\n", > + if (crtc->start_vbl_count && crtc->start_vbl_count != end_vbl_count) { > + DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", > pipe_name(pipe), crtc->start_vbl_count, end_vbl_count, > - ktime_us_delta(end_vbl_time, crtc->start_vbl_time)); > + ktime_us_delta(end_vbl_time, crtc->start_vbl_time), > + crtc->min_vbl, crtc->max_vbl, crtc->scanline_start, > + intel_get_crtc_scanline(crtc)); > + } > } > > static void > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail 2015-09-10 16:05 ` Ville Syrjälä @ 2015-09-10 16:14 ` Jesse Barnes 2015-09-10 20:23 ` Jesse Barnes 1 sibling, 0 replies; 23+ messages in thread From: Jesse Barnes @ 2015-09-10 16:14 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx On 09/10/2015 09:05 AM, Ville Syrjälä wrote: > On Thu, Sep 10, 2015 at 08:34:23AM -0700, Jesse Barnes wrote: >> I used these additional fields to track down the issue I saw on HSW. > > We already have the tracepoints with the scanline information. Not sure > what extra this would give. Saves the trouble of having to dig through tons of tracepoints? _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail 2015-09-10 16:05 ` Ville Syrjälä 2015-09-10 16:14 ` Jesse Barnes @ 2015-09-10 20:23 ` Jesse Barnes 2015-09-14 9:04 ` Daniel Vetter 1 sibling, 1 reply; 23+ messages in thread From: Jesse Barnes @ 2015-09-10 20:23 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx On 09/10/2015 09:05 AM, Ville Syrjälä wrote: > On Thu, Sep 10, 2015 at 08:34:23AM -0700, Jesse Barnes wrote: >> I used these additional fields to track down the issue I saw on HSW. > > We already have the tracepoints with the scanline information. Not sure > what extra this would give. Also when this hits users or test runners, the needed info will be immediately available, rather than having to enable trace points and re-run. I think that's important for error cases like this, as opposed to runtime debugging where tracepoints are fine. Jesse _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail 2015-09-10 20:23 ` Jesse Barnes @ 2015-09-14 9:04 ` Daniel Vetter 0 siblings, 0 replies; 23+ messages in thread From: Daniel Vetter @ 2015-09-14 9:04 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 01:23:53PM -0700, Jesse Barnes wrote: > On 09/10/2015 09:05 AM, Ville Syrjälä wrote: > > On Thu, Sep 10, 2015 at 08:34:23AM -0700, Jesse Barnes wrote: > >> I used these additional fields to track down the issue I saw on HSW. > > > > We already have the tracepoints with the scanline information. Not sure > > what extra this would give. > > Also when this hits users or test runners, the needed info will be > immediately available, rather than having to enable trace points and > re-run. I think that's important for error cases like this, as opposed > to runtime debugging where tracepoints are fine. I agree with Jesse here, if things go south we should be able to print useful debug info. And we do have a bunch of rather mysterious pipe update failure backtraces all over already. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] drm/i915: add more debug info for when atomic updates fail v2 2015-09-10 15:34 ` [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail Jesse Barnes 2015-09-10 16:05 ` Ville Syrjälä @ 2015-09-15 17:03 ` Jesse Barnes 2015-09-15 17:47 ` Ville Syrjälä 1 sibling, 1 reply; 23+ messages in thread From: Jesse Barnes @ 2015-09-15 17:03 UTC (permalink / raw) To: intel-gfx I used these additional fields to track down the issue I saw on HSW. v2: move debug fields into a substruct (Ville) References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> --- drivers/gpu/drm/i915/intel_drv.h | 8 ++++++-- drivers/gpu/drm/i915/intel_sprite.c | 30 +++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 02a755a..1df6ebf 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -565,8 +565,12 @@ struct intel_crtc { int scanline_offset; - unsigned start_vbl_count; - ktime_t start_vbl_time; + struct { + unsigned start_vbl_count; + ktime_t start_vbl_time; + int min_vbl, max_vbl; + int scanline_start; + } debug; struct intel_crtc_atomic_commit atomic; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 4d27243..4c627c4 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -94,8 +94,11 @@ void intel_pipe_update_start(struct intel_crtc *crtc) min = vblank_start - usecs_to_scanlines(mode, 100); max = vblank_start - 1; + crtc->debug.min_vbl = min; + crtc->debug.max_vbl = max; + local_irq_disable(); - crtc->start_vbl_count = 0; + crtc->debug.start_vbl_count = 0; if (min <= 0 || max <= 0) return; @@ -114,8 +117,10 @@ void intel_pipe_update_start(struct intel_crtc *crtc) prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); scanline = intel_get_crtc_scanline(crtc); - if (scanline < min || scanline > max) + if (scanline < min || scanline > max) { + crtc->debug.scanline_start = scanline; break; + } if (timeout <= 0) { DRM_ERROR("Potential atomic update failure on pipe %c\n", @@ -134,11 +139,12 @@ void intel_pipe_update_start(struct intel_crtc *crtc) drm_crtc_vblank_put(&crtc->base); - crtc->start_vbl_time = ktime_get(); - crtc->start_vbl_count = dev->driver->get_vblank_counter(dev, pipe); + crtc->debug.start_vbl_time = ktime_get(); + crtc->debug.start_vbl_count = + dev->driver->get_vblank_counter(dev, pipe); trace_i915_pipe_update_vblank_evaded(crtc, min, max, - crtc->start_vbl_count); + crtc->debug.start_vbl_count); } /** @@ -161,10 +167,16 @@ void intel_pipe_update_end(struct intel_crtc *crtc) local_irq_enable(); - if (crtc->start_vbl_count && crtc->start_vbl_count != end_vbl_count) - DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us\n", - pipe_name(pipe), crtc->start_vbl_count, end_vbl_count, - ktime_us_delta(end_vbl_time, crtc->start_vbl_time)); + if (crtc->debug.start_vbl_count && + crtc->debug.start_vbl_count != end_vbl_count) { + DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", + pipe_name(pipe), crtc->debug.start_vbl_count, + end_vbl_count, + ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), + crtc->debug.min_vbl, crtc->debug.max_vbl, + crtc->debug.scanline_start, + intel_get_crtc_scanline(crtc)); + } } static void -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: add more debug info for when atomic updates fail v2 2015-09-15 17:03 ` [PATCH] drm/i915: add more debug info for when atomic updates fail v2 Jesse Barnes @ 2015-09-15 17:47 ` Ville Syrjälä 0 siblings, 0 replies; 23+ messages in thread From: Ville Syrjälä @ 2015-09-15 17:47 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Tue, Sep 15, 2015 at 10:03:45AM -0700, Jesse Barnes wrote: > I used these additional fields to track down the issue I saw on HSW. > > v2: move debug fields into a substruct (Ville) > > References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > drivers/gpu/drm/i915/intel_drv.h | 8 ++++++-- > drivers/gpu/drm/i915/intel_sprite.c | 30 +++++++++++++++++++++--------- > 2 files changed, 27 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 02a755a..1df6ebf 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -565,8 +565,12 @@ struct intel_crtc { > > int scanline_offset; > > - unsigned start_vbl_count; > - ktime_t start_vbl_time; > + struct { > + unsigned start_vbl_count; > + ktime_t start_vbl_time; > + int min_vbl, max_vbl; > + int scanline_start; > + } debug; > > struct intel_crtc_atomic_commit atomic; > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c > index 4d27243..4c627c4 100644 > --- a/drivers/gpu/drm/i915/intel_sprite.c > +++ b/drivers/gpu/drm/i915/intel_sprite.c > @@ -94,8 +94,11 @@ void intel_pipe_update_start(struct intel_crtc *crtc) > min = vblank_start - usecs_to_scanlines(mode, 100); > max = vblank_start - 1; > > + crtc->debug.min_vbl = min; > + crtc->debug.max_vbl = max; > + > local_irq_disable(); > - crtc->start_vbl_count = 0; > + crtc->debug.start_vbl_count = 0; Could group the debug stuff together. > > if (min <= 0 || max <= 0) > return; > @@ -114,8 +117,10 @@ void intel_pipe_update_start(struct intel_crtc *crtc) > prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); > > scanline = intel_get_crtc_scanline(crtc); > - if (scanline < min || scanline > max) > + if (scanline < min || scanline > max) { > + crtc->debug.scanline_start = scanline; > break; > + } That'll leave the scanline unset if we ever hit the timeout. Shouldn't happen of course, but would still be safer to move the assignment to happen after the loop. It would also allow you to group the debug assignments into one place. > > if (timeout <= 0) { > DRM_ERROR("Potential atomic update failure on pipe %c\n", > @@ -134,11 +139,12 @@ void intel_pipe_update_start(struct intel_crtc *crtc) > > drm_crtc_vblank_put(&crtc->base); > > - crtc->start_vbl_time = ktime_get(); > - crtc->start_vbl_count = dev->driver->get_vblank_counter(dev, pipe); > + crtc->debug.start_vbl_time = ktime_get(); > + crtc->debug.start_vbl_count = > + dev->driver->get_vblank_counter(dev, pipe); > > trace_i915_pipe_update_vblank_evaded(crtc, min, max, > - crtc->start_vbl_count); > + crtc->debug.start_vbl_count); Could also simplify the tracepoint calls a bit by not passing in the debug stuff separately. 'crtc' already gets passed in so the tracepoint can look up everything internally. trace_i915_pipe_update_start() could some similar treatment. > } > > /** > @@ -161,10 +167,16 @@ void intel_pipe_update_end(struct intel_crtc *crtc) > > local_irq_enable(); > > - if (crtc->start_vbl_count && crtc->start_vbl_count != end_vbl_count) > - DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us\n", > - pipe_name(pipe), crtc->start_vbl_count, end_vbl_count, > - ktime_us_delta(end_vbl_time, crtc->start_vbl_time)); > + if (crtc->debug.start_vbl_count && > + crtc->debug.start_vbl_count != end_vbl_count) { > + DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", > + pipe_name(pipe), crtc->debug.start_vbl_count, > + end_vbl_count, > + ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), > + crtc->debug.min_vbl, crtc->debug.max_vbl, > + crtc->debug.scanline_start, > + intel_get_crtc_scanline(crtc)); > + } As with the frame counter and ktime, we should do the read before local_irq_enable() to make sure we get an accurate number. It does mean taking a minor hit for the non-failure case, but if that's a worry we can of course skip the ktime_get() and scanline read unless the frame counter shows a mismatch. > } > > static void > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update 2015-09-10 15:34 [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Jesse Barnes 2015-09-10 15:34 ` [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail Jesse Barnes @ 2015-09-10 16:11 ` Ville Syrjälä 2015-09-10 16:17 ` Jesse Barnes 2015-09-10 21:38 ` [PATCH] drm/i915: workaround bad DSL readout v2 Jesse Barnes 2 siblings, 1 reply; 23+ messages in thread From: Ville Syrjälä @ 2015-09-10 16:11 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 08:34:22AM -0700, Jesse Barnes wrote: > On HSW at least (still testing other platforms, but should be harmless > elsewhere), the DSL reg reads back as 0 when read around vblank start > time. This ends up confusing the atomic start/end checking code, since > it causes the update to appear as if it crossed a frame count boundary. > Workaround that by avoiding updates in the first couple of scanlines. > In testing, even a delay of a single microsecond is enough to give us a > good DSL value again, so the millisecond we'll wait when we hit this > case occasionally ought to be plenty. > > References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > drivers/gpu/drm/i915/intel_sprite.c | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c > index ca7e264..0c2c62f 100644 > --- a/drivers/gpu/drm/i915/intel_sprite.c > +++ b/drivers/gpu/drm/i915/intel_sprite.c > @@ -113,8 +113,16 @@ void intel_pipe_update_start(struct intel_crtc *crtc) > */ > prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); > > + /* > + * On HSW, the DSL reg (0x70000) appears to return 0 if we > + * read it right around the start of vblank. So skip past it > + * so we don't accidentally end up spanning a vblank frame > + * increment, causing the update_end() code to squak at us. > + * (We use 2 in the comparison to account for the > + * scanline_offset used to correct the DSL readout.) > + */ > scanline = intel_get_crtc_scanline(crtc); > - if (scanline < min || scanline > max) > + if (scanline > 2 && (scanline < min || scanline > max)) > break; And it means we'll miss a frame whenever the scanline is 0-2 even on a non-broken. So I don't kike it. Dunno maybe something more targeted like: read dsl if (IS_HASWELL && scanline == crtc->scanline_offset) { udelay(1); read dsl again } in __intel_get_crtc_scanline()? The udelay() is a bit unfortunate, but we'll need accurate scanline informnation for the vblank timestamps too. > > if (timeout <= 0) { > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update 2015-09-10 16:11 ` [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Ville Syrjälä @ 2015-09-10 16:17 ` Jesse Barnes 2015-09-10 16:27 ` Ville Syrjälä 0 siblings, 1 reply; 23+ messages in thread From: Jesse Barnes @ 2015-09-10 16:17 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx On 09/10/2015 09:11 AM, Ville Syrjälä wrote: > On Thu, Sep 10, 2015 at 08:34:22AM -0700, Jesse Barnes wrote: >> On HSW at least (still testing other platforms, but should be harmless >> elsewhere), the DSL reg reads back as 0 when read around vblank start >> time. This ends up confusing the atomic start/end checking code, since >> it causes the update to appear as if it crossed a frame count boundary. >> Workaround that by avoiding updates in the first couple of scanlines. >> In testing, even a delay of a single microsecond is enough to give us a >> good DSL value again, so the millisecond we'll wait when we hit this >> case occasionally ought to be plenty. >> >> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 >> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> >> --- >> drivers/gpu/drm/i915/intel_sprite.c | 10 +++++++++- >> 1 file changed, 9 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c >> index ca7e264..0c2c62f 100644 >> --- a/drivers/gpu/drm/i915/intel_sprite.c >> +++ b/drivers/gpu/drm/i915/intel_sprite.c >> @@ -113,8 +113,16 @@ void intel_pipe_update_start(struct intel_crtc *crtc) >> */ >> prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); >> >> + /* >> + * On HSW, the DSL reg (0x70000) appears to return 0 if we >> + * read it right around the start of vblank. So skip past it >> + * so we don't accidentally end up spanning a vblank frame >> + * increment, causing the update_end() code to squak at us. >> + * (We use 2 in the comparison to account for the >> + * scanline_offset used to correct the DSL readout.) >> + */ >> scanline = intel_get_crtc_scanline(crtc); >> - if (scanline < min || scanline > max) >> + if (scanline > 2 && (scanline < min || scanline > max)) >> break; > > And it means we'll miss a frame whenever the scanline is 0-2 even on a > non-broken. So I don't kike it. We only stall 1ms in the timeout later, so we shouldn't miss a frame, we'll just queue the update in the middle of it instead, right? > > Dunno maybe something more targeted like: > > read dsl > if (IS_HASWELL && scanline == crtc->scanline_offset) { > udelay(1); > read dsl again > } > in __intel_get_crtc_scanline()? > > The udelay() is a bit unfortunate, but we'll need accurate scanline > informnation for the vblank timestamps too. Yeah, hiding it in the get_crtc_scanline() might be better; it would be good to know if this affects other platforms as well though. More testing is needed for that. Jesse _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update 2015-09-10 16:17 ` Jesse Barnes @ 2015-09-10 16:27 ` Ville Syrjälä 0 siblings, 0 replies; 23+ messages in thread From: Ville Syrjälä @ 2015-09-10 16:27 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 09:17:23AM -0700, Jesse Barnes wrote: > On 09/10/2015 09:11 AM, Ville Syrjälä wrote: > > On Thu, Sep 10, 2015 at 08:34:22AM -0700, Jesse Barnes wrote: > >> On HSW at least (still testing other platforms, but should be harmless > >> elsewhere), the DSL reg reads back as 0 when read around vblank start > >> time. This ends up confusing the atomic start/end checking code, since > >> it causes the update to appear as if it crossed a frame count boundary. > >> Workaround that by avoiding updates in the first couple of scanlines. > >> In testing, even a delay of a single microsecond is enough to give us a > >> good DSL value again, so the millisecond we'll wait when we hit this > >> case occasionally ought to be plenty. > >> > >> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > >> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > >> --- > >> drivers/gpu/drm/i915/intel_sprite.c | 10 +++++++++- > >> 1 file changed, 9 insertions(+), 1 deletion(-) > >> > >> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c > >> index ca7e264..0c2c62f 100644 > >> --- a/drivers/gpu/drm/i915/intel_sprite.c > >> +++ b/drivers/gpu/drm/i915/intel_sprite.c > >> @@ -113,8 +113,16 @@ void intel_pipe_update_start(struct intel_crtc *crtc) > >> */ > >> prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); > >> > >> + /* > >> + * On HSW, the DSL reg (0x70000) appears to return 0 if we > >> + * read it right around the start of vblank. So skip past it > >> + * so we don't accidentally end up spanning a vblank frame > >> + * increment, causing the update_end() code to squak at us. > >> + * (We use 2 in the comparison to account for the > >> + * scanline_offset used to correct the DSL readout.) > >> + */ > >> scanline = intel_get_crtc_scanline(crtc); > >> - if (scanline < min || scanline > max) > >> + if (scanline > 2 && (scanline < min || scanline > max)) > >> break; > > > > And it means we'll miss a frame whenever the scanline is 0-2 even on a > > non-broken. So I don't kike it. > > We only stall 1ms in the timeout later, so we shouldn't miss a frame, we'll just queue the update in the middle of it instead, right? Hmm. Right I forgot the 1ms timeout. Well, it's susceptible to scheduling delays since we've re-enabled the interrupts and all, so there's no guarantee that it's just 1ms. Also once we'll retry the loop we'll just bail out if the timeout has already expired, so there's really no guarantee anymore that we won't be in the danger zone when we enter the crirical section. > > > > > Dunno maybe something more targeted like: > > > > read dsl > > if (IS_HASWELL && scanline == crtc->scanline_offset) { > > udelay(1); > > read dsl again > > } > > in __intel_get_crtc_scanline()? > > > > The udelay() is a bit unfortunate, but we'll need accurate scanline > > informnation for the vblank timestamps too. > > Yeah, hiding it in the get_crtc_scanline() might be better; it would be good to know if this affects other platforms as well though. More testing is needed for that. > > Jesse -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 15:34 [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Jesse Barnes 2015-09-10 15:34 ` [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail Jesse Barnes 2015-09-10 16:11 ` [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Ville Syrjälä @ 2015-09-10 21:38 ` Jesse Barnes 2015-09-10 21:53 ` Ville Syrjälä ` (2 more replies) 2 siblings, 3 replies; 23+ messages in thread From: Jesse Barnes @ 2015-09-10 21:38 UTC (permalink / raw) To: intel-gfx On HSW at least (still testing other platforms, but should be harmless elsewhere), the DSL reg reads back as 0 when read around vblank start time. This ends up confusing the atomic start/end checking code, since it causes the update to appear as if it crossed a frame count boundary. Avoid the problem by making sure we don't return scanline_offset from the get_crtc_scanline function. In moving the code there, I add to add an additional delay since it could be called and have a legitimate 0 result for some time (depending on the pixel clock). v2: move hsw dsl read hack to get_crtc_scanline (Ville) References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> --- drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 90bc6c2..97e5d52 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; /* + * On HSW, the DSL reg (0x70000) appears to return 0 if we + * read it right around the start of vblank. So try it again + * so we don't accidentally end up spanning a vblank frame + * increment, causing the pipe_update_end() code to squak at us. + */ + if (IS_HASWELL(dev) && !position) { + int i, temp; + + for (i = 0; i < 100; i++) { + udelay(1); + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & + DSL_LINEMASK_GEN3; + if (temp != position) { + position = temp; + goto out; + } + } + } + +out: + /* * See update_scanline_offset() for the details on the * scanline_offset adjustment. */ -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 21:38 ` [PATCH] drm/i915: workaround bad DSL readout v2 Jesse Barnes @ 2015-09-10 21:53 ` Ville Syrjälä 2015-09-10 21:57 ` Jesse Barnes 2015-09-14 18:47 ` Ville Syrjälä 2015-09-22 16:41 ` Ville Syrjälä 2 siblings, 1 reply; 23+ messages in thread From: Ville Syrjälä @ 2015-09-10 21:53 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: > On HSW at least (still testing other platforms, but should be harmless > elsewhere), the DSL reg reads back as 0 when read around vblank start > time. This ends up confusing the atomic start/end checking code, since > it causes the update to appear as if it crossed a frame count boundary. > Avoid the problem by making sure we don't return scanline_offset from > the get_crtc_scanline function. In moving the code there, I add to add > an additional delay since it could be called and have a legitimate 0 > result for some time (depending on the pixel clock). > > v2: move hsw dsl read hack to get_crtc_scanline (Ville) > > References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 90bc6c2..97e5d52 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > > /* > + * On HSW, the DSL reg (0x70000) appears to return 0 if we > + * read it right around the start of vblank. So try it again > + * so we don't accidentally end up spanning a vblank frame > + * increment, causing the pipe_update_end() code to squak at us. > + */ > + if (IS_HASWELL(dev) && !position) { > + int i, temp; > + > + for (i = 0; i < 100; i++) { > + udelay(1); > + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > + DSL_LINEMASK_GEN3; > + if (temp != position) { > + position = temp; > + goto out; > + } > + } > + } Hmm. Another idea. If it always happens at start of vbl, maybe have a look at the ISR. If scanline reads 0, but ISR says we're in vblank, just return vblank_start. That's assming ISR would in fact show that it's in vblank when this happens. > + > +out: > + /* > * See update_scanline_offset() for the details on the > * scanline_offset adjustment. > */ > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 21:53 ` Ville Syrjälä @ 2015-09-10 21:57 ` Jesse Barnes 2015-09-10 22:33 ` Ville Syrjälä 0 siblings, 1 reply; 23+ messages in thread From: Jesse Barnes @ 2015-09-10 21:57 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx On 09/10/2015 02:53 PM, Ville Syrjälä wrote: > On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: >> On HSW at least (still testing other platforms, but should be harmless >> elsewhere), the DSL reg reads back as 0 when read around vblank start >> time. This ends up confusing the atomic start/end checking code, since >> it causes the update to appear as if it crossed a frame count boundary. >> Avoid the problem by making sure we don't return scanline_offset from >> the get_crtc_scanline function. In moving the code there, I add to add >> an additional delay since it could be called and have a legitimate 0 >> result for some time (depending on the pixel clock). >> >> v2: move hsw dsl read hack to get_crtc_scanline (Ville) >> >> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 >> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> >> --- >> drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ >> 1 file changed, 21 insertions(+) >> >> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c >> index 90bc6c2..97e5d52 100644 >> --- a/drivers/gpu/drm/i915/i915_irq.c >> +++ b/drivers/gpu/drm/i915/i915_irq.c >> @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) >> position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; >> >> /* >> + * On HSW, the DSL reg (0x70000) appears to return 0 if we >> + * read it right around the start of vblank. So try it again >> + * so we don't accidentally end up spanning a vblank frame >> + * increment, causing the pipe_update_end() code to squak at us. >> + */ >> + if (IS_HASWELL(dev) && !position) { >> + int i, temp; >> + >> + for (i = 0; i < 100; i++) { >> + udelay(1); >> + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & >> + DSL_LINEMASK_GEN3; >> + if (temp != position) { >> + position = temp; >> + goto out; >> + } >> + } >> + } > > Hmm. Another idea. If it always happens at start of vbl, maybe have a > look at the ISR. If scanline reads 0, but ISR says we're in vblank, just > return vblank_start. That's assming ISR would in fact show that it's in > vblank when this happens. Sounds a bit racy, though I guess it wouldn't hurt. I'm actually a little dubious about this change anyway since it will mean longer delays when we really are at the top of the field/frame. You sure you don't like the first one better? Thanks, Jesse _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 21:57 ` Jesse Barnes @ 2015-09-10 22:33 ` Ville Syrjälä 2015-09-14 9:10 ` Daniel Vetter 2015-09-15 21:00 ` Jesse Barnes 0 siblings, 2 replies; 23+ messages in thread From: Ville Syrjälä @ 2015-09-10 22:33 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 02:57:32PM -0700, Jesse Barnes wrote: > On 09/10/2015 02:53 PM, Ville Syrjälä wrote: > > On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: > >> On HSW at least (still testing other platforms, but should be harmless > >> elsewhere), the DSL reg reads back as 0 when read around vblank start > >> time. This ends up confusing the atomic start/end checking code, since > >> it causes the update to appear as if it crossed a frame count boundary. > >> Avoid the problem by making sure we don't return scanline_offset from > >> the get_crtc_scanline function. In moving the code there, I add to add > >> an additional delay since it could be called and have a legitimate 0 > >> result for some time (depending on the pixel clock). > >> > >> v2: move hsw dsl read hack to get_crtc_scanline (Ville) > >> > >> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > >> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > >> --- > >> drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ > >> 1 file changed, 21 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > >> index 90bc6c2..97e5d52 100644 > >> --- a/drivers/gpu/drm/i915/i915_irq.c > >> +++ b/drivers/gpu/drm/i915/i915_irq.c > >> @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > >> position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > >> > >> /* > >> + * On HSW, the DSL reg (0x70000) appears to return 0 if we > >> + * read it right around the start of vblank. So try it again > >> + * so we don't accidentally end up spanning a vblank frame > >> + * increment, causing the pipe_update_end() code to squak at us. > >> + */ > >> + if (IS_HASWELL(dev) && !position) { > >> + int i, temp; > >> + > >> + for (i = 0; i < 100; i++) { > >> + udelay(1); > >> + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > >> + DSL_LINEMASK_GEN3; > >> + if (temp != position) { > >> + position = temp; > >> + goto out; > >> + } > >> + } > >> + } > > > > Hmm. Another idea. If it always happens at start of vbl, maybe have a > > look at the ISR. If scanline reads 0, but ISR says we're in vblank, just > > return vblank_start. That's assming ISR would in fact show that it's in > > vblank when this happens. > > Sounds a bit racy, Not too much I think. We're under spinlock_irqsave here, and if the scanline should magically start to tick just after we've read it we would still give almost the right answer, even if we got magically delayed by one or two scanlines. That's assuming that it has already latched the double buffered registers when it goes wonky. If the register latching happens only when the counter starts working again, well then we're in deeper doodoo. But then I wouldn't expect ISR to indicate that we're in vblank then either. So I think you should definitely check what the ISR actually tells you while things are in the bad state. In case the badness happens just before start of vblank, well, then I have no good idea how to handle it. This sort of retry loop is the best that comes to mind right now :( > though I guess it wouldn't hurt. I'm actually a > little dubious about this change anyway since it will mean longer delays > when we really are at the top of the field/frame. You sure you don't > like the first one better? The first one can't help vblank timestamps. Although I suppose that if the badness always cures itself before the interrupt gets raised, we would not hit this normally when we update the timestamp from the irq handler. We could hit it when updating the timestamp outside the irq handler though (ie. during vblank_get/put etc.). -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 22:33 ` Ville Syrjälä @ 2015-09-14 9:10 ` Daniel Vetter 2015-09-14 13:02 ` Ville Syrjälä 2015-09-15 21:00 ` Jesse Barnes 1 sibling, 1 reply; 23+ messages in thread From: Daniel Vetter @ 2015-09-14 9:10 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx On Fri, Sep 11, 2015 at 01:33:08AM +0300, Ville Syrjälä wrote: > On Thu, Sep 10, 2015 at 02:57:32PM -0700, Jesse Barnes wrote: > > On 09/10/2015 02:53 PM, Ville Syrjälä wrote: > > > On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: > > >> On HSW at least (still testing other platforms, but should be harmless > > >> elsewhere), the DSL reg reads back as 0 when read around vblank start > > >> time. This ends up confusing the atomic start/end checking code, since > > >> it causes the update to appear as if it crossed a frame count boundary. > > >> Avoid the problem by making sure we don't return scanline_offset from > > >> the get_crtc_scanline function. In moving the code there, I add to add > > >> an additional delay since it could be called and have a legitimate 0 > > >> result for some time (depending on the pixel clock). > > >> > > >> v2: move hsw dsl read hack to get_crtc_scanline (Ville) > > >> > > >> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > > >> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > >> --- > > >> drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ > > >> 1 file changed, 21 insertions(+) > > >> > > >> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > > >> index 90bc6c2..97e5d52 100644 > > >> --- a/drivers/gpu/drm/i915/i915_irq.c > > >> +++ b/drivers/gpu/drm/i915/i915_irq.c > > >> @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > > >> position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > > >> > > >> /* > > >> + * On HSW, the DSL reg (0x70000) appears to return 0 if we > > >> + * read it right around the start of vblank. So try it again > > >> + * so we don't accidentally end up spanning a vblank frame > > >> + * increment, causing the pipe_update_end() code to squak at us. > > >> + */ > > >> + if (IS_HASWELL(dev) && !position) { > > >> + int i, temp; > > >> + > > >> + for (i = 0; i < 100; i++) { > > >> + udelay(1); > > >> + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > > >> + DSL_LINEMASK_GEN3; > > >> + if (temp != position) { > > >> + position = temp; > > >> + goto out; > > >> + } > > >> + } > > >> + } > > > > > > Hmm. Another idea. If it always happens at start of vbl, maybe have a > > > look at the ISR. If scanline reads 0, but ISR says we're in vblank, just > > > return vblank_start. That's assming ISR would in fact show that it's in > > > vblank when this happens. > > > > Sounds a bit racy, > > Not too much I think. We're under spinlock_irqsave here, and if the > scanline should magically start to tick just after we've read it we > would still give almost the right answer, even if we got magically > delayed by one or two scanlines. That's assuming that it has already > latched the double buffered registers when it goes wonky. If the > register latching happens only when the counter starts working again, > well then we're in deeper doodoo. But then I wouldn't expect ISR to > indicate that we're in vblank then either. So I think you should > definitely check what the ISR actually tells you while things are > in the bad state. There's still a race 1. we read bogus vblank counter 2. vblank processing completes in hw 3. ISR indicates where out of vblank. So you'd need at least a loop to make sure you're 0 vblank counter is stable across the ISR read. -Daniel > In case the badness happens just before start of vblank, well, then > I have no good idea how to handle it. This sort of retry loop is > the best that comes to mind right now :( > > > though I guess it wouldn't hurt. I'm actually a > > little dubious about this change anyway since it will mean longer delays > > when we really are at the top of the field/frame. You sure you don't > > like the first one better? > > The first one can't help vblank timestamps. Although I suppose that if > the badness always cures itself before the interrupt gets raised, we > would not hit this normally when we update the timestamp from the irq > handler. We could hit it when updating the timestamp outside the irq > handler though (ie. during vblank_get/put etc.). On top of that there's patches floating from Chris to get a vblank timestamp without grabbing the interrupts temporarily or any spinlock. That helps when we immediately disable the interrupt and then a bit later the compositors asks for the current vblank to estimate the next frame. So if possible I'd definitely vote to share this "fix up bonghits vblank" logic if possible ... -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-14 9:10 ` Daniel Vetter @ 2015-09-14 13:02 ` Ville Syrjälä 2015-09-14 14:29 ` Daniel Vetter 0 siblings, 1 reply; 23+ messages in thread From: Ville Syrjälä @ 2015-09-14 13:02 UTC (permalink / raw) To: Daniel Vetter; +Cc: intel-gfx On Mon, Sep 14, 2015 at 11:10:04AM +0200, Daniel Vetter wrote: > On Fri, Sep 11, 2015 at 01:33:08AM +0300, Ville Syrjälä wrote: > > On Thu, Sep 10, 2015 at 02:57:32PM -0700, Jesse Barnes wrote: > > > On 09/10/2015 02:53 PM, Ville Syrjälä wrote: > > > > On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: > > > >> On HSW at least (still testing other platforms, but should be harmless > > > >> elsewhere), the DSL reg reads back as 0 when read around vblank start > > > >> time. This ends up confusing the atomic start/end checking code, since > > > >> it causes the update to appear as if it crossed a frame count boundary. > > > >> Avoid the problem by making sure we don't return scanline_offset from > > > >> the get_crtc_scanline function. In moving the code there, I add to add > > > >> an additional delay since it could be called and have a legitimate 0 > > > >> result for some time (depending on the pixel clock). > > > >> > > > >> v2: move hsw dsl read hack to get_crtc_scanline (Ville) > > > >> > > > >> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > > > >> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > > >> --- > > > >> drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ > > > >> 1 file changed, 21 insertions(+) > > > >> > > > >> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > > > >> index 90bc6c2..97e5d52 100644 > > > >> --- a/drivers/gpu/drm/i915/i915_irq.c > > > >> +++ b/drivers/gpu/drm/i915/i915_irq.c > > > >> @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > > > >> position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > > > >> > > > >> /* > > > >> + * On HSW, the DSL reg (0x70000) appears to return 0 if we > > > >> + * read it right around the start of vblank. So try it again > > > >> + * so we don't accidentally end up spanning a vblank frame > > > >> + * increment, causing the pipe_update_end() code to squak at us. > > > >> + */ > > > >> + if (IS_HASWELL(dev) && !position) { > > > >> + int i, temp; > > > >> + > > > >> + for (i = 0; i < 100; i++) { > > > >> + udelay(1); > > > >> + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > > > >> + DSL_LINEMASK_GEN3; > > > >> + if (temp != position) { > > > >> + position = temp; > > > >> + goto out; > > > >> + } > > > >> + } > > > >> + } > > > > > > > > Hmm. Another idea. If it always happens at start of vbl, maybe have a > > > > look at the ISR. If scanline reads 0, but ISR says we're in vblank, just > > > > return vblank_start. That's assming ISR would in fact show that it's in > > > > vblank when this happens. > > > > > > Sounds a bit racy, > > > > Not too much I think. We're under spinlock_irqsave here, and if the > > scanline should magically start to tick just after we've read it we > > would still give almost the right answer, even if we got magically > > delayed by one or two scanlines. That's assuming that it has already > > latched the double buffered registers when it goes wonky. If the > > register latching happens only when the counter starts working again, > > well then we're in deeper doodoo. But then I wouldn't expect ISR to > > indicate that we're in vblank then either. So I think you should > > definitely check what the ISR actually tells you while things are > > in the bad state. > > There's still a race > 1. we read bogus vblank counter > 2. vblank processing completes in hw > 3. ISR indicates where out of vblank. > > So you'd need at least a loop to make sure you're 0 vblank counter is > stable across the ISR read. Seems rather unlikely. That would mean something blocked us for the entire duration of the vblank. > -Daniel > > > In case the badness happens just before start of vblank, well, then > > I have no good idea how to handle it. This sort of retry loop is > > the best that comes to mind right now :( > > > > > though I guess it wouldn't hurt. I'm actually a > > > little dubious about this change anyway since it will mean longer delays > > > when we really are at the top of the field/frame. You sure you don't > > > like the first one better? > > > > The first one can't help vblank timestamps. Although I suppose that if > > the badness always cures itself before the interrupt gets raised, we > > would not hit this normally when we update the timestamp from the irq > > handler. We could hit it when updating the timestamp outside the irq > > handler though (ie. during vblank_get/put etc.). > > On top of that there's patches floating from Chris to get a vblank > timestamp without grabbing the interrupts temporarily or any spinlock. > That helps when we immediately disable the interrupt and then a bit later > the compositors asks for the current vblank to estimate the next frame. I think we all already agreed that it's not going to fly. If we don't ask the hw how many vblanks we lost we can't give userspace any kind of accurate information. > So if possible I'd definitely vote to share this "fix up bonghits vblank" > logic if possible ... I have no idea what you're looking to share and with whom. I do not want workarounds for hardware specific bugs in the shared vblank code. We already had that due to radeon, and that stuff has been doing nothing for us except hinder attempts at making the code work sanely for sane Intel hardware. Which reminds me, I need to post a pile of vblank patches... -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-14 13:02 ` Ville Syrjälä @ 2015-09-14 14:29 ` Daniel Vetter 0 siblings, 0 replies; 23+ messages in thread From: Daniel Vetter @ 2015-09-14 14:29 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx On Mon, Sep 14, 2015 at 04:02:44PM +0300, Ville Syrjälä wrote: > On Mon, Sep 14, 2015 at 11:10:04AM +0200, Daniel Vetter wrote: > > On Fri, Sep 11, 2015 at 01:33:08AM +0300, Ville Syrjälä wrote: > > > On Thu, Sep 10, 2015 at 02:57:32PM -0700, Jesse Barnes wrote: > > > > On 09/10/2015 02:53 PM, Ville Syrjälä wrote: > > > > > On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: > > > > >> On HSW at least (still testing other platforms, but should be harmless > > > > >> elsewhere), the DSL reg reads back as 0 when read around vblank start > > > > >> time. This ends up confusing the atomic start/end checking code, since > > > > >> it causes the update to appear as if it crossed a frame count boundary. > > > > >> Avoid the problem by making sure we don't return scanline_offset from > > > > >> the get_crtc_scanline function. In moving the code there, I add to add > > > > >> an additional delay since it could be called and have a legitimate 0 > > > > >> result for some time (depending on the pixel clock). > > > > >> > > > > >> v2: move hsw dsl read hack to get_crtc_scanline (Ville) > > > > >> > > > > >> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > > > > >> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > > > >> --- > > > > >> drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ > > > > >> 1 file changed, 21 insertions(+) > > > > >> > > > > >> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > > > > >> index 90bc6c2..97e5d52 100644 > > > > >> --- a/drivers/gpu/drm/i915/i915_irq.c > > > > >> +++ b/drivers/gpu/drm/i915/i915_irq.c > > > > >> @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > > > > >> position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > > > > >> > > > > >> /* > > > > >> + * On HSW, the DSL reg (0x70000) appears to return 0 if we > > > > >> + * read it right around the start of vblank. So try it again > > > > >> + * so we don't accidentally end up spanning a vblank frame > > > > >> + * increment, causing the pipe_update_end() code to squak at us. > > > > >> + */ > > > > >> + if (IS_HASWELL(dev) && !position) { > > > > >> + int i, temp; > > > > >> + > > > > >> + for (i = 0; i < 100; i++) { > > > > >> + udelay(1); > > > > >> + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > > > > >> + DSL_LINEMASK_GEN3; > > > > >> + if (temp != position) { > > > > >> + position = temp; > > > > >> + goto out; > > > > >> + } > > > > >> + } > > > > >> + } > > > > > > > > > > Hmm. Another idea. If it always happens at start of vbl, maybe have a > > > > > look at the ISR. If scanline reads 0, but ISR says we're in vblank, just > > > > > return vblank_start. That's assming ISR would in fact show that it's in > > > > > vblank when this happens. > > > > > > > > Sounds a bit racy, > > > > > > Not too much I think. We're under spinlock_irqsave here, and if the > > > scanline should magically start to tick just after we've read it we > > > would still give almost the right answer, even if we got magically > > > delayed by one or two scanlines. That's assuming that it has already > > > latched the double buffered registers when it goes wonky. If the > > > register latching happens only when the counter starts working again, > > > well then we're in deeper doodoo. But then I wouldn't expect ISR to > > > indicate that we're in vblank then either. So I think you should > > > definitely check what the ISR actually tells you while things are > > > in the bad state. > > > > There's still a race > > 1. we read bogus vblank counter > > 2. vblank processing completes in hw > > 3. ISR indicates where out of vblank. > > > > So you'd need at least a loop to make sure you're 0 vblank counter is > > stable across the ISR read. > > Seems rather unlikely. That would mean something blocked us for the entire > duration of the vblank. > > > -Daniel > > > > > In case the badness happens just before start of vblank, well, then > > > I have no good idea how to handle it. This sort of retry loop is > > > the best that comes to mind right now :( > > > > > > > though I guess it wouldn't hurt. I'm actually a > > > > little dubious about this change anyway since it will mean longer delays > > > > when we really are at the top of the field/frame. You sure you don't > > > > like the first one better? > > > > > > The first one can't help vblank timestamps. Although I suppose that if > > > the badness always cures itself before the interrupt gets raised, we > > > would not hit this normally when we update the timestamp from the irq > > > handler. We could hit it when updating the timestamp outside the irq > > > handler though (ie. during vblank_get/put etc.). > > > > On top of that there's patches floating from Chris to get a vblank > > timestamp without grabbing the interrupts temporarily or any spinlock. > > That helps when we immediately disable the interrupt and then a bit later > > the compositors asks for the current vblank to estimate the next frame. > > I think we all already agreed that it's not going to fly. If we don't > ask the hw how many vblanks we lost we can't give userspace any kind > of accurate information. > > > So if possible I'd definitely vote to share this "fix up bonghits vblank" > > logic if possible ... > > I have no idea what you're looking to share and with whom. I do not want > workarounds for hardware specific bugs in the shared vblank code. We > already had that due to radeon, and that stuff has been doing nothing > for us except hinder attempts at making the code work sanely for sane > Intel hardware. > > Which reminds me, I need to post a pile of vblank patches... s/vblank/scanline/ in all of the above since I was confused again. And I just thought if we have some special hacks to make the get_scanline function cope with hw oddity that should be used by the vblank time stamp code too. But that's the case already (if we put the hack into __intel_get_crtc_scanline). -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 22:33 ` Ville Syrjälä 2015-09-14 9:10 ` Daniel Vetter @ 2015-09-15 21:00 ` Jesse Barnes 1 sibling, 0 replies; 23+ messages in thread From: Jesse Barnes @ 2015-09-15 21:00 UTC (permalink / raw) To: Ville Syrjälä; +Cc: intel-gfx On 09/10/2015 03:33 PM, Ville Syrjälä wrote: > On Thu, Sep 10, 2015 at 02:57:32PM -0700, Jesse Barnes wrote: >> On 09/10/2015 02:53 PM, Ville Syrjälä wrote: >>> On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: >>>> On HSW at least (still testing other platforms, but should be harmless >>>> elsewhere), the DSL reg reads back as 0 when read around vblank start >>>> time. This ends up confusing the atomic start/end checking code, since >>>> it causes the update to appear as if it crossed a frame count boundary. >>>> Avoid the problem by making sure we don't return scanline_offset from >>>> the get_crtc_scanline function. In moving the code there, I add to add >>>> an additional delay since it could be called and have a legitimate 0 >>>> result for some time (depending on the pixel clock). >>>> >>>> v2: move hsw dsl read hack to get_crtc_scanline (Ville) >>>> >>>> References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 >>>> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> >>>> --- >>>> drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ >>>> 1 file changed, 21 insertions(+) >>>> >>>> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c >>>> index 90bc6c2..97e5d52 100644 >>>> --- a/drivers/gpu/drm/i915/i915_irq.c >>>> +++ b/drivers/gpu/drm/i915/i915_irq.c >>>> @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) >>>> position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; >>>> >>>> /* >>>> + * On HSW, the DSL reg (0x70000) appears to return 0 if we >>>> + * read it right around the start of vblank. So try it again >>>> + * so we don't accidentally end up spanning a vblank frame >>>> + * increment, causing the pipe_update_end() code to squak at us. >>>> + */ >>>> + if (IS_HASWELL(dev) && !position) { >>>> + int i, temp; >>>> + >>>> + for (i = 0; i < 100; i++) { >>>> + udelay(1); >>>> + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & >>>> + DSL_LINEMASK_GEN3; >>>> + if (temp != position) { >>>> + position = temp; >>>> + goto out; >>>> + } >>>> + } >>>> + } >>> >>> Hmm. Another idea. If it always happens at start of vbl, maybe have a >>> look at the ISR. If scanline reads 0, but ISR says we're in vblank, just >>> return vblank_start. That's assming ISR would in fact show that it's in >>> vblank when this happens. >> >> Sounds a bit racy, > > Not too much I think. We're under spinlock_irqsave here, and if the > scanline should magically start to tick just after we've read it we > would still give almost the right answer, even if we got magically > delayed by one or two scanlines. That's assuming that it has already > latched the double buffered registers when it goes wonky. If the > register latching happens only when the counter starts working again, > well then we're in deeper doodoo. But then I wouldn't expect ISR to > indicate that we're in vblank then either. So I think you should > definitely check what the ISR actually tells you while things are > in the bad state. > > In case the badness happens just before start of vblank, well, then > I have no good idea how to handle it. This sort of retry loop is > the best that comes to mind right now :( > >> though I guess it wouldn't hurt. I'm actually a >> little dubious about this change anyway since it will mean longer delays >> when we really are at the top of the field/frame. You sure you don't >> like the first one better? > > The first one can't help vblank timestamps. Although I suppose that if > the badness always cures itself before the interrupt gets raised, we > would not hit this normally when we update the timestamp from the irq > handler. We could hit it when updating the timestamp outside the irq > handler though (ie. during vblank_get/put etc.). > Ok so just for the record, I've tried a few things: - using the ISR to check the vblank and vsync status when this occurs (both are clear) - using the transcoder debug reg for reading the scanline (also returns 0) so I think we're stuck with one of the two approaches already posted. As for affecting the vblank timestamps, I think you're right that this bug shouldn't affect that. The issue (a 0 return from the PIPEDSL read) seems to manifest just as the frame counter should be getting incremented. By the time we actually raise an interrupt or move to the next scanline, the correct value is returned. So even if we stuff the workaround into the pipe update start function (which should be more tolerant of delays in general) I think we'll be safe. What do you prefer? Do you want any changes on top of either of the previous patches given the above? Thanks, Jesse _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 21:38 ` [PATCH] drm/i915: workaround bad DSL readout v2 Jesse Barnes 2015-09-10 21:53 ` Ville Syrjälä @ 2015-09-14 18:47 ` Ville Syrjälä 2015-09-22 16:41 ` Ville Syrjälä 2 siblings, 0 replies; 23+ messages in thread From: Ville Syrjälä @ 2015-09-14 18:47 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: > On HSW at least (still testing other platforms, but should be harmless > elsewhere), the DSL reg reads back as 0 when read around vblank start > time. This ends up confusing the atomic start/end checking code, since > it causes the update to appear as if it crossed a frame count boundary. > Avoid the problem by making sure we don't return scanline_offset from > the get_crtc_scanline function. In moving the code there, I add to add > an additional delay since it could be called and have a legitimate 0 > result for some time (depending on the pixel clock). > > v2: move hsw dsl read hack to get_crtc_scanline (Ville) > > References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 90bc6c2..97e5d52 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > > /* > + * On HSW, the DSL reg (0x70000) appears to return 0 if we > + * read it right around the start of vblank. So try it again > + * so we don't accidentally end up spanning a vblank frame > + * increment, causing the pipe_update_end() code to squak at us. > + */ > + if (IS_HASWELL(dev) && !position) { > + int i, temp; > + > + for (i = 0; i < 100; i++) { > + udelay(1); > + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > + DSL_LINEMASK_GEN3; > + if (temp != position) { > + position = temp; > + goto out; > + } > + } > + } I mentioned this on irc, but I'll repeat here so we have it on record somewhere; There's another scanline register on hsw+ in the transcoder. We should definitely check if that suffers from the same fault. -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v2 2015-09-10 21:38 ` [PATCH] drm/i915: workaround bad DSL readout v2 Jesse Barnes 2015-09-10 21:53 ` Ville Syrjälä 2015-09-14 18:47 ` Ville Syrjälä @ 2015-09-22 16:41 ` Ville Syrjälä 2015-09-22 19:15 ` [PATCH] drm/i915: workaround bad DSL readout v3 Jesse Barnes 2 siblings, 1 reply; 23+ messages in thread From: Ville Syrjälä @ 2015-09-22 16:41 UTC (permalink / raw) To: Jesse Barnes; +Cc: intel-gfx On Thu, Sep 10, 2015 at 02:38:53PM -0700, Jesse Barnes wrote: > On HSW at least (still testing other platforms, but should be harmless > elsewhere), the DSL reg reads back as 0 when read around vblank start > time. This ends up confusing the atomic start/end checking code, since > it causes the update to appear as if it crossed a frame count boundary. > Avoid the problem by making sure we don't return scanline_offset from > the get_crtc_scanline function. In moving the code there, I add to add > an additional delay since it could be called and have a legitimate 0 > result for some time (depending on the pixel clock). > > v2: move hsw dsl read hack to get_crtc_scanline (Ville) > > References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 90bc6c2..97e5d52 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -697,6 +697,27 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > > /* > + * On HSW, the DSL reg (0x70000) appears to return 0 if we > + * read it right around the start of vblank. So try it again Make that "just before the start of vblank". Otherwise I'm sure I'll forget the details and start to think again about using ISR tricks. > + * so we don't accidentally end up spanning a vblank frame > + * increment, causing the pipe_update_end() code to squak at us. > + */ > + if (IS_HASWELL(dev) && !position) { > + int i, temp; > + > + for (i = 0; i < 100; i++) { > + udelay(1); > + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > + DSL_LINEMASK_GEN3; > + if (temp != position) { > + position = temp; > + goto out; break is enough A bit nasty this loop with irqs off, but it's the only way we can avoid corrupted vblank timestamps from happening when the hardware is on the fritz. With the comment updatead and goto killed: Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > + } > + } > + } > + > +out: > + /* > * See update_scanline_offset() for the details on the > * scanline_offset adjustment. > */ > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] drm/i915: workaround bad DSL readout v3 2015-09-22 16:41 ` Ville Syrjälä @ 2015-09-22 19:15 ` Jesse Barnes 2015-09-23 7:48 ` Jani Nikula 0 siblings, 1 reply; 23+ messages in thread From: Jesse Barnes @ 2015-09-22 19:15 UTC (permalink / raw) To: intel-gfx On HSW at least (still testing other platforms, but should be harmless elsewhere), the DSL reg reads back as 0 when read around vblank start time. This ends up confusing the atomic start/end checking code, since it causes the update to appear as if it crossed a frame count boundary. Avoid the problem by making sure we don't return scanline_offset from the get_crtc_scanline function. In moving the code there, I add to add an additional delay since it could be called and have a legitimate 0 result for some time (depending on the pixel clock). v2: move hsw dsl read hack to get_crtc_scanline (Ville) v3: use break instead of goto (Ville) update comment with workaround details (Ville) References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> --- drivers/gpu/drm/i915/i915_irq.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1f53061..a8aa797 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -697,6 +697,32 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; /* + * On HSW, the DSL reg (0x70000) appears to return 0 if we + * read it just before the start of vblank. So try it again + * so we don't accidentally end up spanning a vblank frame + * increment, causing the pipe_update_end() code to squak at us. + * + * The nature of this problem means we can't simply check the ISR + * bit and return the vblank start value; nor can we use the scanline + * debug register in the transcoder as it appears to have the same + * problem. We may need to extend this to include other platforms, + * but so far testing only shows the problem on HSW. + */ + if (IS_HASWELL(dev) && !position) { + int i, temp; + + for (i = 0; i < 100; i++) { + udelay(1); + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & + DSL_LINEMASK_GEN3; + if (temp != position) { + position = temp; + break; + } + } + } + + /* * See update_scanline_offset() for the details on the * scanline_offset adjustment. */ -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH] drm/i915: workaround bad DSL readout v3 2015-09-22 19:15 ` [PATCH] drm/i915: workaround bad DSL readout v3 Jesse Barnes @ 2015-09-23 7:48 ` Jani Nikula 0 siblings, 0 replies; 23+ messages in thread From: Jani Nikula @ 2015-09-23 7:48 UTC (permalink / raw) To: Jesse Barnes, intel-gfx On Tue, 22 Sep 2015, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > On HSW at least (still testing other platforms, but should be harmless > elsewhere), the DSL reg reads back as 0 when read around vblank start > time. This ends up confusing the atomic start/end checking code, since > it causes the update to appear as if it crossed a frame count boundary. > Avoid the problem by making sure we don't return scanline_offset from > the get_crtc_scanline function. In moving the code there, I add to add > an additional delay since it could be called and have a legitimate 0 > result for some time (depending on the pixel clock). > > v2: move hsw dsl read hack to get_crtc_scanline (Ville) > v3: use break instead of goto (Ville) > update comment with workaround details (Ville) > > References: https://bugs.freedesktop.org/show_bug.cgi?id=91579 > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Pushed to drm-intel-fixes, thanks for the patch and review. Sorry for the delay, I failed to notice the patch had been reviewed. It would have helped if the patch had the Reviewed-by: tag already in place, or the reviewer (or someone else pointing at the review) had replied with the Reviewed-by: tag. I spend very little time looking at individual patches, especially if the appearance is that there's discussion going on. BR, Jani. > --- > drivers/gpu/drm/i915/i915_irq.c | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 1f53061..a8aa797 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -697,6 +697,32 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) > position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; > > /* > + * On HSW, the DSL reg (0x70000) appears to return 0 if we > + * read it just before the start of vblank. So try it again > + * so we don't accidentally end up spanning a vblank frame > + * increment, causing the pipe_update_end() code to squak at us. > + * > + * The nature of this problem means we can't simply check the ISR > + * bit and return the vblank start value; nor can we use the scanline > + * debug register in the transcoder as it appears to have the same > + * problem. We may need to extend this to include other platforms, > + * but so far testing only shows the problem on HSW. > + */ > + if (IS_HASWELL(dev) && !position) { > + int i, temp; > + > + for (i = 0; i < 100; i++) { > + udelay(1); > + temp = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & > + DSL_LINEMASK_GEN3; > + if (temp != position) { > + position = temp; > + break; > + } > + } > + } > + > + /* > * See update_scanline_offset() for the details on the > * scanline_offset adjustment. > */ > -- > 1.9.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2015-09-23 7:45 UTC | newest] Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-09-10 15:34 [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Jesse Barnes 2015-09-10 15:34 ` [PATCH 2/2] drm/i915: add more debug info for when atomic updates fail Jesse Barnes 2015-09-10 16:05 ` Ville Syrjälä 2015-09-10 16:14 ` Jesse Barnes 2015-09-10 20:23 ` Jesse Barnes 2015-09-14 9:04 ` Daniel Vetter 2015-09-15 17:03 ` [PATCH] drm/i915: add more debug info for when atomic updates fail v2 Jesse Barnes 2015-09-15 17:47 ` Ville Syrjälä 2015-09-10 16:11 ` [PATCH 1/2] drm/i915: workaround bad DSL readout in start of pipe update Ville Syrjälä 2015-09-10 16:17 ` Jesse Barnes 2015-09-10 16:27 ` Ville Syrjälä 2015-09-10 21:38 ` [PATCH] drm/i915: workaround bad DSL readout v2 Jesse Barnes 2015-09-10 21:53 ` Ville Syrjälä 2015-09-10 21:57 ` Jesse Barnes 2015-09-10 22:33 ` Ville Syrjälä 2015-09-14 9:10 ` Daniel Vetter 2015-09-14 13:02 ` Ville Syrjälä 2015-09-14 14:29 ` Daniel Vetter 2015-09-15 21:00 ` Jesse Barnes 2015-09-14 18:47 ` Ville Syrjälä 2015-09-22 16:41 ` Ville Syrjälä 2015-09-22 19:15 ` [PATCH] drm/i915: workaround bad DSL readout v3 Jesse Barnes 2015-09-23 7:48 ` Jani Nikula
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.