vblank problem (and proposed fix) on crtc > 1
Ilija Hadzic
ihadzic at research.bell-labs.com
Thu Mar 10 05:32:49 PST 2011
On Thu, 10 Mar 2011, Michel [ISO-8859-1] Dänzer wrote:
>
> I'm afraid I don't really like this. Apart from the ugly bogus error
> message, the probes could fail for other reasons, e.g. at some point we
> might want to return an error when the ioctl is called for a CRTC which
> is currently disabled, to avoid the hang you were getting for CRTC 1.
>
Your example actually speaks in favor of probing. Let's say that the
future kernel starts returning an error for disabled CRTC and you don't do
any probing. DDX will start calling vblank waits on disabled CRTC (just
like it's doing now) and spam the kernel with errors. With probing, error
will happen only once at screen init time.
> Dave's drm-next tree actually has a new DRM_IOCTL_GET_CAP ioctl, which
> could be used for detecting this capability. It might even be possible
> to handle old kernels transparently in drmWaitVBlank(), but I'm not sure
> offhand if that would be better overall than doing it in the driver
> code.
>
This argument is self defeating. The purpose of the probing is to check
for the old kernel. If I have DRM_IOCTL_GET_CAP, that means that I have a
new kernel so probing will just work. If I have an old kernel then I don't
have DRM_IOCTL_GET_CAP ioctl, so attemting to use it will result in an
error from the kernel anyway. It makes no sense to me to cause an error
in one ioctl so that you would prevent an error in other ioctl.
>> + if (info->high_crtc_works) {
>> + high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) &
>> + DRM_VBLANK_HIGH_CRTC_MASK;
>> + } else vbl.request.type |= DRM_VBLANK_SECONDARY;
>
> Waiting on a random other CRTC makes no sense. If you know you can't
> wait on the given CRTC, don't wait at all.
>
It's not random CRTC, but it's what today's DDX and DRM call "secondary"
CRTC. I intentionally did this for two reasons. First, this is the
behavior that is identical to what we see today, and I prefer to preserve
the same behavior if either component is old (DDX or kernel), rather than
have different behavior for different combinations of old/new. The second
reason is pragmatic, if you want to not call wait_vblank at all and make
sure you are safe to whatever the code above you is doing and not
return an error you have to make up the sequence numbers and timestamps
(and probably keep track of them) and that's much more radical
modification to the DDX. So I figured this would be conservative.
>> + vbl.request.sequence = 0;
>> + if (drmWaitVBlank(info->dri2.drm_fd, &vbl)) {
>> + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Kernel rejects VBLANK request on CRTC %d\n", c);
>> + info->high_crtc_works = FALSE;
>
> Should break out of the for loop at this point.
>
This was also intentional. I want to see in Xorg log file the full list of
crtcs that rejected the vblank wait request. It comes handy for analyzing
the problems and/or bugs.
More information about the dri-devel
mailing list