From 406359bba154e60aab2a14666eb5e183c1c0e1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 24 Jul 2017 10:50:49 +0800 Subject: [PATCH] gpu-kms: poll() on KMS fd on EAGAIN When drmHandleEvent() returns an error and errno is set to EAGAIN, instead of ending up in a busy loop, poll() the fd until there is anything to read. https://bugzilla.gnome.org/show_bug.cgi?id=785381 --- src/backends/native/meta-gpu-kms.c | 45 +++++++++++++++++++--- src/backends/native/meta-gpu-kms.h | 3 +- src/backends/native/meta-renderer-native.c | 4 +- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 775ed349d..0b70c3864 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -80,7 +81,7 @@ kms_event_dispatch (GSource *source, { MetaKmsSource *kms_source = (MetaKmsSource *) source; - meta_gpu_kms_wait_for_flip (kms_source->gpu_kms); + meta_gpu_kms_wait_for_flip (kms_source->gpu_kms, NULL); return G_SOURCE_CONTINUE; } @@ -256,18 +257,52 @@ page_flip_handler (int fd, invoke_flip_closure (flip_closure); } -void -meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms) +gboolean +meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms, + GError **error) { drmEventContext evctx; if (gpu_kms->page_flips_not_supported) - return; + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Page flips not supported"); + return FALSE; + } memset (&evctx, 0, sizeof evctx); evctx.version = DRM_EVENT_CONTEXT_VERSION; evctx.page_flip_handler = page_flip_handler; - drmHandleEvent (gpu_kms->fd, &evctx); + + while (TRUE) + { + if (drmHandleEvent (gpu_kms->fd, &evctx) != 0) + { + struct pollfd pfd; + int ret; + + if (errno != EAGAIN) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + strerror (errno)); + return FALSE; + } + + pfd.fd = gpu_kms->fd; + pfd.events = POLL_IN | POLL_ERR; + do + { + ret = poll (&pfd, 1, -1); + } + while (ret == -1 && errno == EINTR); + } + else + { + break; + } + } + + return TRUE; } void diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h index 001fc95b4..6c7d5a312 100644 --- a/src/backends/native/meta-gpu-kms.h +++ b/src/backends/native/meta-gpu-kms.h @@ -62,7 +62,8 @@ gboolean meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms, GClosure *flip_closure, gboolean *fb_in_use); -void meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms); +gboolean meta_gpu_kms_wait_for_flip (MetaGpuKms *gpu_kms, + GError **error); int meta_gpu_kms_get_fd (MetaGpuKms *gpu_kms); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 4fdaeb426..8a54e9b4e 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -944,7 +944,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, * animation earlier due to the animation being driven by some other monitor. */ while (onscreen_native->pending_flips) - meta_gpu_kms_wait_for_flip (gpu_kms); + meta_gpu_kms_wait_for_flip (gpu_kms, NULL); parent_vtable->onscreen_swap_buffers_with_damage (onscreen, rectangles, @@ -1658,7 +1658,7 @@ meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native, * to swap the current buffer. */ while (onscreen_native->gbm.next_fb_id != 0) - meta_gpu_kms_wait_for_flip (gpu_kms); + meta_gpu_kms_wait_for_flip (gpu_kms, NULL); /* Need to drop the GBM surface and create a new one */