[Intel-gfx] [PATCH 1/3] drm/i915: Check for a stalled page flip after each vblank
Chris Wilson
chris at chris-wilson.co.uk
Tue Jun 10 13:33:48 CEST 2014
On Tue, Jun 10, 2014 at 02:25:50PM +0300, Ville Syrjälä wrote:
> On Tue, Jun 10, 2014 at 11:04:00AM +0100, Chris Wilson wrote:
> > +static inline int crtc_sbc(struct intel_crtc *crtc)
> > +{
> > + return atomic_read(&crtc->base.dev->vblank[crtc->pipe].count);
> > +}
>
> Still says 'sbc' which doesn't make sense to me.
I just don't like the term msc. :-p
crtc_vblank_counter()?
> > +
> > static inline void intel_mark_page_flip_active(struct intel_crtc *intel_crtc)
> > {
> > /* Ensure that the work item is consistent when activating it ... */
> > smp_wmb();
> > atomic_set(&intel_crtc->unpin_work->pending, INTEL_FLIP_PENDING);
> > + intel_crtc->unpin_work->sbc = crtc_sbc(intel_crtc);
> > /* and that it is marked active as soon as the irq could fire. */
> > smp_wmb();
> > }
> > @@ -9265,6 +9279,69 @@ static int intel_default_queue_flip(struct drm_device *dev,
> > return -ENODEV;
> > }
> >
> > +static bool i915_gem_object_is_idle(struct drm_i915_gem_object *obj,
> > + bool readonly)
> > +{
> > + struct intel_engine_cs *ring = obj->ring;
> > + u32 seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
> > +
> > + if (ring == NULL || seqno == 0)
> > + return true;
> > +
> > + return i915_seqno_passed(ring->get_seqno(ring, true), seqno);
> > +}
> > +
> > +static bool __intel_pageflip_stall_check(struct drm_device *dev,
> > + struct drm_crtc *crtc)
> > +{
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > + struct intel_unpin_work *work = intel_crtc->unpin_work;
> > + u32 addr;
> > +
> > + if (atomic_read(&work->pending) >= INTEL_FLIP_COMPLETE)
> > + return true;
> > +
> > + if (!work->enable_stall_check)
> > + return false;
> > +
> > + if ((crtc_sbc(intel_crtc) - intel_crtc->unpin_work->sbc) < 3)
> > + return false;
> > +
> > + if (!i915_gem_object_is_idle(work->pending_flip_obj, true))
> > + return false;
>
> I take it this is done to mitigate my premature flip completion
> concerns? Should work for the common case I suppose. Although if
> someone does something like this "write,read(s),flip" it could
> still complete the flip too soon. Waiting for last_read_seqno would
> avoid that.
It actually predated your concerns. I considered the person who continues
to write to the pending fb and decided that I didn't care too much for
them. What I actually wanted to do was to capture the vblank counter for
when the object was idle and then start watching for a missed flip.
Indeed, tracking when we believe the flip was queued would be better
again.
> And double checking the hardware flip counter should avoid this
> problem entirely. We already have it sampled in unpin_work->flip_count
> for the mmio vs. cs flip race so it should be easy to check it here as
> well. I suppose having both the flip counter and seqno checks should
> provide the best protection for all gens.
That was half the reason for waiting for that series to land first. Just
I never adapted to the framecounter code.
> As far as the seqno check goes, I was wondering if we should sample
> the seqno when submitting the flip? I'm slightly worried how this will
> work if userspace submitted a flip and already managed to pile more
> rendering on top. This code would then wait for the seqno for those
> later rendering operations.
Right that is how mmio flips avoid this issue.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list