[PATCH] drm-vblank: Always return true vblank count of scheduled vblank event.
Jesse Barnes
jbarnes at virtuousgeek.org
Mon Dec 13 09:30:12 PST 2010
On Mon, 13 Dec 2010 18:21:20 +0100
Mario Kleiner <mario.kleiner at tuebingen.mpg.de> wrote:
> On Dec 10, 2010, at 6:45 PM, Jesse Barnes wrote:
>
> > On Fri, 10 Dec 2010 16:00:19 +0100
> > Mario Kleiner <mario.kleiner at tuebingen.mpg.de> wrote:
> >
> >>
> >>
> >> -------- Original Message --------
> >> Subject: [PATCH] drm-vblank: Always return true vblank count of
> >> scheduled vblank event.
> >> Date: Fri, 10 Dec 2010 15:58:10 +0100
> >> From: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
> >> To: airlied at gmail.com
> >> CC: jbarnes at virtuousgeek.org, krh at bitplanet.net, Mario Kleiner
> >> <mario.kleiner at tuebingen.mpg.de>
> >>
> >> This patch tries to make sure that the vbl.reply.sequence
> >> vblank count for a queued or emitted vblank event always
> >> corresponds to the true vblank count of queueing/emission, so
> >> the ddx can rely on the returned target_msc for consistency
> >> checks and implementation of swap_intervals in glXSwapBuffers().
> >>
> >> Without this there is a small race-condition between the
> >> userspace ddx queueing a vblank event and the vblank
> >> counter incrementing before the event gets queued in
> >> the kernel.
> >>
> >> Signed-off-by: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
> >> ---
> >> drivers/gpu/drm/drm_irq.c | 3 +++
> >> 1 files changed, 3 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> >> index 4e82d0d..55160d7 100644
> >> --- a/drivers/gpu/drm/drm_irq.c
> >> +++ b/drivers/gpu/drm/drm_irq.c
> >> @@ -1086,15 +1086,18 @@ static int drm_queue_vblank_event(struct
> >> drm_device *dev, int pipe,
> >>
> >> e->event.sequence = vblwait->request.sequence;
> >> if ((seq - vblwait->request.sequence) <= (1 << 23)) {
> >> + e->event.sequence = seq;
> >> e->event.tv_sec = now.tv_sec;
> >> e->event.tv_usec = now.tv_usec;
> >> drm_vblank_put(dev, e->pipe);
> >> list_add_tail(&e->base.link, &e->base.file_priv->event_list);
> >> wake_up_interruptible(&e->base.file_priv->event_wait);
> >> + vblwait->reply.sequence = seq;
> >> trace_drm_vblank_event_delivered(current->pid, pipe,
> >> vblwait->request.sequence);
> >
> > But this actually causes us to return the current count rather than
> > the
> > requested count if the event requested is in the past, right?
> >
>
> Yes. But i think that's what the spec wants. The wording in the spec
> is usually "...and then will return the current values for UST, MSC,
> and SBC...". If it just returned what was passed to it, it
> wouldn't provide any new information to the calling client.
>
> Currently there are three uses for queuing of vblank events:
>
> a) Copy-Swaps: Queue a vblank event for target_msc to trigger a blit
> once the event is received. Because we set the
> DRM_VBLANK_NEXT_ON_MISS flag when queuing this event, the requested
> target_msc is automatically adapted by the drm to current_msc + 1 and
> this new adapted value is returned to the ddx. So for copy swaps the
> kernel returns the true expected count and time of the swap. The
> above path isn't ever taken.
>
> b) Pageflip-Swaps: Queue a vblank event for target_msc - 1, even if
> target_msc -1 is already over. This will deliver the event
> immediately if current_msc >= target_msc - 1, but without the patch
> it would deliver it with a vbl.reply.sequence that has nothing to do
> with the real count at swap.
>
> So a) and b) with the old code don't have a negative effect on
> scheduling a swap, but b) can have a a negative effect for the
> scheduling of the next pageflipped swap: The ddx uses the returned
> value as last_swap_target to implement swap_interval correctly, so
> the next swap may not obey the swap_interval correctly if case b)
> delivered an outdated vbl.reply.sequence number.
>
> c) WaitForMscOML: Like b), but here it would return the "wrong" count
> for a target_msc in the past. The client would get the information
> back that it passed into the call, instead of the information that
> reflects reality.
>
> d) Some correctness check for pageflipping in the ddx that can work
> more reliable / detect more possible errors if the returned value is
> always precise.
>
> >> } else {
> >> list_add_tail(&e->base.link, &dev->vblank_event_list);
> >> + vblwait->reply.sequence = vblwait->request.sequence;
> >> }
> >
> > This one makes sense; we want to make sure the returned sequence is
> > the
> > one requested (assuming it was in the future at the time of the
> > request
> > anyway).
> >
>
> Yes, but the requested number gets adapted by the function if
> DRM_VBLANK_NEXT_ON_MISS is set. Also this statement is a bit
> redundant, because vblwait is a union iirc, so vblwait-
> >reply.sequence and vblwait->request.sequence are actually the same
> field. It's just added for clarity.
Right; thanks for the additional explanation, it looks good to me.
Acked-by: Jesse Barnes <jbarnes at virtuousgeek.org>
--
Jesse Barnes, Intel Open Source Technology Center
More information about the dri-devel
mailing list