summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPovilas Kanapickas <povilas@radix.lt>2021-04-16 16:15:35 +0300
committerPovilas Kanapickas <povilas@radix.lt>2021-06-15 12:53:33 +0300
commit1a1bd5cf7a1a3364afb625f020e1c013fbabfbb6 (patch)
tree4e55b042cb66a1c57382c25e7b602df7a4317a17 /hw
parent9992245c5f7821de1fbd866f43f0afe55080ed67 (diff)
modesetting: Add a limit on async page flip error log frequency
In certain circumstances we will have a lot of flip errors without a reasonable way to prevent them. In such case we reduce the number of logged messages to at least not fill the error logs. The details are as follows: At least on i915 hardware support for async page flip support depends on the used modifiers which themselves can change dynamically for a screen. This results in the following problems: - We can't know about whether a particular CRTC will be able to do an async flip without hardcoding the same logic as the kernel as there's no interface to query this information. - There is no way to give this information to an application, because the protocol of the present extension does not specify anything about changing of the capabilities on runtime or the need to re-query them. Even if the above was solved, the only benefit would be avoiding a roundtrip to the kernel and reduced amount of error logs. The former does not seem to be a good enough benefit compared to the amount of work that would need to be done. The latter is solved in this commit. Reviewed-by: Eero Tamminen <eero.t.tamminen@intel.com> Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/drivers/modesetting/pageflip.c74
1 files changed, 71 insertions, 3 deletions
diff --git a/hw/xfree86/drivers/modesetting/pageflip.c b/hw/xfree86/drivers/modesetting/pageflip.c
index 6b86f1e9e..d943a4dd4 100644
--- a/hw/xfree86/drivers/modesetting/pageflip.c
+++ b/hw/xfree86/drivers/modesetting/pageflip.c
@@ -225,6 +225,76 @@ queue_flip_on_crtc(ScreenPtr screen, xf86CrtcPtr crtc,
}
+#define MS_ASYNC_FLIP_LOG_ENABLE_LOGS_INTERVAL_MS 10000
+#define MS_ASYNC_FLIP_LOG_FREQUENT_LOGS_INTERVAL_MS 1000
+#define MS_ASYNC_FLIP_FREQUENT_LOG_COUNT 10
+
+static void
+ms_print_pageflip_error(int screen_index, const char *log_prefix,
+ int crtc_index, int flags, int err)
+{
+ /* In certain circumstances we will have a lot of flip errors without a
+ * reasonable way to prevent them. In such case we reduce the number of
+ * logged messages to at least not fill the error logs.
+ *
+ * The details are as follows:
+ *
+ * At least on i915 hardware support for async page flip support depends
+ * on the used modifiers which themselves can change dynamically for a
+ * screen. This results in the following problems:
+ *
+ * - We can't know about whether a particular CRTC will be able to do an
+ * async flip without hardcoding the same logic as the kernel as there's
+ * no interface to query this information.
+ *
+ * - There is no way to give this information to an application, because
+ * the protocol of the present extension does not specify anything about
+ * changing of the capabilities on runtime or the need to re-query them.
+ *
+ * Even if the above was solved, the only benefit would be avoiding a
+ * roundtrip to the kernel and reduced amount of error logs. The former
+ * does not seem to be a good enough benefit compared to the amount of work
+ * that would need to be done. The latter is solved below. */
+
+ static CARD32 error_last_time_ms;
+ static int frequent_logs;
+ static Bool logs_disabled;
+
+ if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+ CARD32 curr_time_ms = GetTimeInMillis();
+ int clocks_since_last_log = curr_time_ms - error_last_time_ms;
+
+ if (clocks_since_last_log >
+ MS_ASYNC_FLIP_LOG_ENABLE_LOGS_INTERVAL_MS) {
+ frequent_logs = 0;
+ logs_disabled = FALSE;
+ }
+ if (!logs_disabled) {
+ if (clocks_since_last_log <
+ MS_ASYNC_FLIP_LOG_FREQUENT_LOGS_INTERVAL_MS) {
+ frequent_logs++;
+ }
+
+ if (frequent_logs > MS_ASYNC_FLIP_FREQUENT_LOG_COUNT) {
+ xf86DrvMsg(screen_index, X_WARNING,
+ "%s: detected too frequent flip errors, disabling "
+ "logs until frequency is reduced\n", log_prefix);
+ logs_disabled = TRUE;
+ } else {
+ xf86DrvMsg(screen_index, X_WARNING,
+ "%s: queue async flip during flip on CRTC %d failed: %s\n",
+ log_prefix, crtc_index, strerror(err));
+ }
+ }
+ error_last_time_ms = curr_time_ms;
+ } else {
+ xf86DrvMsg(screen_index, X_WARNING,
+ "%s: queue flip during flip on CRTC %d failed: %s\n",
+ log_prefix, crtc_index, strerror(err));
+ }
+}
+
+
Bool
ms_do_pageflip(ScreenPtr screen,
PixmapPtr new_front,
@@ -334,9 +404,7 @@ ms_do_pageflip(ScreenPtr screen,
log_prefix, i);
goto error_undo;
case QUEUE_FLIP_DRM_FLUSH_FAILED:
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "%s: queue flip during flip on CRTC %d failed: %s\n",
- log_prefix, i, strerror(errno));
+ ms_print_pageflip_error(scrn->scrnIndex, log_prefix, i, flags, errno);
goto error_undo;
case QUEUE_FLIP_SUCCESS:
break;