[PATCH] drm-vblank: Always return true vblank count of scheduled vblank event.

Mario Kleiner mario.kleiner at tuebingen.mpg.de
Mon Dec 13 09:21:20 PST 2010

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.


More information about the dri-devel mailing list