Bug 28383

Summary: Cloned screens with different res/refresh cause problems with mesa demos since new dri2 vsync.
Product: xorg Reporter: Andy Furniss <adf.lists>
Component: Server/GeneralAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: mario.kleiner, nbowler
Version: git   
Hardware: All   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 27592    
Attachments:
Description Flags
Testpatch for dualhead hang when moving windows.
none
Fix hang in glXSwapBuffers if drawable has moved between crtc's. none

Description Andy Furniss 2010-06-04 04:28:02 UTC
I think this is linked to the new dri2 vsync but mat be wrong...

rv670 mesa git, ddx git xorg git (2 weeks ago) drt kernels.

Not just latest drt and unrelated to tiling patches.

I am starting with a TV connected @ 1024x768 + vga monitor @ 1920x1080 so the top left section of the monitor screen gets tv(50Hz) vsync - monitor is 60Hz.

If I start a mesa demo and it starts in the TV area it will sync to 50HZ if I move it outside the top left area it will sync to 60Hz.

The problem is if I then move it back to the TV area it will stop rendering and become unresponsive. I can <ctrl><c> it but the window will remain. If I the move the window around enough I can get xserver to segfault.

This doesn't happen with UMS or a drt from 29th April (uses old vsync).
It doesn't happen if I disable TV with xrandr.

[   489.682] 0: /home/andy/Src/Xorg-git/modular/bin/Xorg (xorg_backtrace+0x3b) [0x80da21b]
[   489.682] 1: /home/andy/Src/Xorg-git/modular/bin/Xorg (0x8048000+0x59ca5) [0x80a1ca5]
[   489.682] 2: (vdso) (__kernel_rt_sigreturn+0x0) [0xffffe40c]
[   489.682] 3: /home/andy/Src/Xorg-git/modular/bin/Xorg (LocalClient+0x41) [0x809d8d1]
[   489.682] 4: /home/andy/Src/Xorg-git/modular/lib/xorg/modules/extensions/libdri2.so (0xb73ce000+0x309b) [0xb73d109b]
[   489.682] 5: /home/andy/Src/Xorg-git/modular/bin/Xorg (0x8048000+0x25198) [0x806d198]
[   489.682] 6: /home/andy/Src/Xorg-git/modular/bin/Xorg (0x8048000+0x1a86a) [0x806286a]
[   489.682] 7: /lib/libc.so.6 (__libc_start_main+0xd0) [0xb7495380]
[   489.682] 8: /home/andy/Src/Xorg-git/modular/bin/Xorg (0x8048000+0x1a481) [0x8062481]
[   489.682] Segmentation fault at address 0x18
Comment 1 Michel Dänzer 2010-06-04 08:49:58 UTC
DRI2 synchronization is handled by the X driver.
Comment 2 Mario Kleiner 2010-06-09 06:45:36 UTC
Created attachment 36178 [details] [review]
Testpatch for dualhead hang when moving windows.

This quick & dirty patch disables the pPriv->last_swap_target mechanism for implementing arbitrary swap_intervals for glXSwapBuffers with the DRI2 swap & sync bits. Any swap interval > 0 is effectively treated as a swap interval of 1 (=vsync'ed swap). A zero swap_interval means immediate swap.

This should avoid hangs of windows (no longer updating) when they are moved from a crtc with a higher refresh rate (e.g., 60 Hz) to a crtc with a lower refresh rate (e.g., 50 Hz).

Assumed reason for the hang is that crtc's with different refresh rate will differ / drift apart in their vblank counts after some time has passed. For each drawable, the x-server keeps track of the last vblank count for which a bufferswap was scheduled for a drawable in pPriv->last_swap_target. In successive glXSwapBuffers() calls, this value is used as baseline for scheduling the swap to satisfy the chosen pPriv->swap_interval. If a window moves between crtc's, pPriv->last_swap_target is not updated prior to swap to take the difference in vblank counts between old and new crtc into account. Therefore a swap is scheduled far in the future, which causes the window to hang for many seconds or minutes.

This quick & dirty patch forces swap at next vblank if swap_interval is > 0, ignoring the stale last_swap_target value.
Comment 3 Andy Furniss 2010-06-10 08:11:12 UTC
(In reply to comment #2)
> Created an attachment (id=36178) [details]
> Testpatch for dualhead hang when moving windows.

I will test this - but current (unpatched) xserver master is not working for me, so it may not be today if I run out of time finding why.
Comment 4 Andy Furniss 2010-06-11 06:58:24 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > Created an attachment (id=36178) [details] [details]
> > Testpatch for dualhead hang when moving windows.
> 
> I will test this - but current (unpatched) xserver master is not working for
> me, so it may not be today if I run out of time finding why.

The Patch fixes the issue, I had to apply by hand on the latest xserver master that works for me.
Comment 5 Mario Kleiner 2010-06-13 08:45:46 UTC
Created attachment 36250 [details] [review]
Fix hang in glXSwapBuffers if drawable has moved between crtc's.

Thanks for testing. If you want you can try this new patch as well - you'll need to revert the old one first. It is a more clever solution, i already tested in on a dual-head machine and will send it for inclusion into master / 1.8. But a bit of extra testing never hurts.

This patch detects if a drawable has moved from a "faster" crtc with higher refresh rate to a "slower" crtc with lower refresh rate. If so, it resets last_swap_target to the current vblank count of the current slow crtc to avoid the hang. The patch does nothing when moving from a slow to a fast crtc as that fixes itself automagically.
Comment 6 Andy Furniss 2010-06-14 08:30:34 UTC
(In reply to comment #5)
> Created an attachment (id=36250) [details]
> Fix hang in glXSwapBuffers if drawable has moved between crtc's.

This patch also works OK.
Comment 7 Alex Deucher 2010-06-15 14:47:25 UTC
Patch sent to the list as well:
http://lists.x.org/archives/xorg-devel/2010-June/010094.html
Comment 8 Mario Kleiner 2010-06-18 10:20:31 UTC
Thanks for testing. Fix is now in master, i'm closing the bug.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.