summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner.de@gmail.com>2018-02-27 06:51:59 +0100
committerAdam Jackson <ajax@redhat.com>2018-02-27 10:02:05 -0500
commitefe9e3e9ff96a06f50d94dc93ad2c19085fa3d09 (patch)
tree3421495c0604224f5fc843573f748bd53d721bce
parent8171d4c2d67b2990a278dc018ac32534c3afe606 (diff)
modesetting: Fix fallback for lack of new vblank kernel API.
Turns out that the kernel DRM ioctl handling returns EINVAL instead of ENOTTY if one tries to call the new drmCrtcGetSequence() or drmCrtcQueueSequence() ioctl's introduced in Linux 4.15 on an older kernel where they are missing. This causes the fallback code not to fall back to the old drmWaitVblank() ioctl and thereby failure of vblank stuff. E.g., on Linux 4.13, glxgears -info runs unthrottled at 10000 fps instead of 60 fps. Also breakage of OML_sync_control extension. Check for errno != EINVAL before setting has_queue_sequence = TRUE. Additionally in case of supported drmCrtcQueueSequence(), set has_queue_sequence = TRUE on success, or we might get at least a temporary failure in ms_queue_vblank(). One slight ambiguity is that we can also get EINVAL if drm_crtc_vblank_get() fails in the kernel, so if that happened at first invocation of the new api, we'd fall back to drmWaitVblank() and then fail there, instead of failing in the new api, but the end result would be the same. Fixes: 44d5f2eb8a2f ("xf86-video-modesetting: Support new vblank kernel API [v2]") Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Cc: Keith Packard <keithp@keithp.com> Reviewed-by: Keith Packard <keithp@keithp.com>
-rw-r--r--hw/xfree86/drivers/modesetting/vblank.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index e7879f504..1d331ccdb 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -189,7 +189,7 @@ ms_get_kernel_ust_msc(xf86CrtcPtr crtc,
ret = drmCrtcGetSequence(ms->fd, drmmode_crtc->mode_crtc->crtc_id,
msc, &ns);
- if (ret != -1 || errno != ENOTTY) {
+ if (ret != -1 || (errno != ENOTTY && errno != EINVAL)) {
ms->has_queue_sequence = TRUE;
if (ret == 0)
*ust = ns / 1000;
@@ -246,10 +246,11 @@ ms_queue_vblank(xf86CrtcPtr crtc, ms_queue_flag flags,
if (ret == 0) {
if (msc_queued)
*msc_queued = ms_kernel_msc_to_crtc_msc(crtc, kernel_queued);
+ ms->has_queue_sequence = TRUE;
return TRUE;
}
- if (ret != -1 || errno != ENOTTY) {
+ if (ret != -1 || (errno != ENOTTY && errno != EINVAL)) {
ms->has_queue_sequence = TRUE;
goto check;
}