For OpenGL programs, it was possible to override this using ~/.drirc or a vblank_mode=0 environment variable. It's easy to demonstrate this using glxgears, for example comparing "glxgears" to "vblank_mode=0 glxgears". With mplayer, it can be overridden using "-vo gl:swapinterval=0", but there doesn't seem to be a way to override it for "-vo vdpau".
Driconf is a nice graphical tool for changing ~/.drirc settings. However, I needed to edit the resulting ~/.drirc, changing to
These are just partial workarounds. The real problem is that unhandled interrupts cause the kernel to disable the radeon IRQ. This is the IRQ used for waiting for vertical retrace, and I guess that wait times out after 0.1s. When things work properly, I can see radeon interrupt count increasing in /proc/interrupts while running glxgears and for a few moments afterwards. When things don't work properly, that count is 200000 and this appears in dmesg:
[ 33.806034] irq 5: nobody cared (try booting with the "irqpoll" option)
followed by a long backtrace and
[ 33.806980] handlers:
[ 33.807173] [<e8a57cc0>] radeon_driver_irq_handler_kms
[ 33.807180] Disabling IRQ #5
This happened about 5 seconds after all the drm initialization messages. As you can see, the radeon irq handler was there. It just acted as if the interrupt was not from the video card. Earlier on there is:
[ 24.047694] ACPI: PCI Interrupt Link [LNKA] enabled at IRQ 5
[ 24.047707] PCI: setting IRQ 5 as level-triggered
[ 24.047723] radeon 0000:01:00.0: PCI INT A -> Link[LNKA] -> GSI 5 (level, low) -> IRQ 5
Since the interrupt is level triggered, I don't think it would be reasonable to use the
noirqdebugkernel option to prevent the interrupt from being disabled. It would just keep interrupting and make everything slow or even unresponsive.