xserver: Branch 'master' - 2 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Mar 27 08:21:56 UTC 2023
hw/xwayland/xwayland-present.c | 27 +++++++++++++++++++++++++++
hw/xwayland/xwayland-present.h | 3 +++
hw/xwayland/xwayland-window.c | 39 +++++++++++++++------------------------
3 files changed, 45 insertions(+), 24 deletions(-)
New commits:
commit 754d6b6dd0a9ec42d75247596a8885bf54352ee7
Author: Michel Dänzer <mdaenzer at redhat.com>
Date: Fri Mar 10 12:39:30 2023 +0100
xwayland: Prevent nested xwl_present_for_each_frame_callback calls
It could happen with the following call path:
frame_callback
xwl_present_frame_callback
xwl_present_msc_bump
xwl_present_execute
xwl_present_flip
xwl_window_create_frame_callback
The nested loop called xwl_present_reset_timer, which may end up calling
xorg_list_del for the entry after the one frame_callback started the
chain for. This resulted in the outer loop never terminating, because
its next element wasn't hooked up to the list anymore.
We avoid this by calling xwl_present_reset_timer as needed in
frame_callback, and bailing from xwl_window_create_frame_callback if it
was called from the former.
We also catch nested calls and FatalError if they ever happen again due
to another bug.
v2:
* Leave xwl_present_reset_timer call in xwl_present_frame_callback,
needed if xwl_present_msc_bump didn't hook up the window to the frame
callback list again.
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1442
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index e8a173774..189e7cfd6 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -89,16 +89,31 @@ xwl_present_event_from_id(uint64_t event_id)
return (struct xwl_present_event*)(uintptr_t)event_id;
}
+static Bool entered_for_each_frame_callback;
+
+Bool
+xwl_present_entered_for_each_frame_callback(void)
+{
+ return entered_for_each_frame_callback;
+}
+
void
xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
void iter_func(struct xwl_present_window *))
{
struct xwl_present_window *xwl_present_window, *tmp;
+ if (entered_for_each_frame_callback)
+ FatalError("Nested xwl_present_for_each_frame_callback call");
+
+ entered_for_each_frame_callback = TRUE;
+
xorg_list_for_each_entry_safe(xwl_present_window, tmp,
&xwl_window->frame_callback_list,
frame_callback_list)
iter_func(xwl_present_window);
+
+ entered_for_each_frame_callback = FALSE;
}
static void
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 620e6c5ca..806272089 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -61,6 +61,7 @@ struct xwl_present_event {
PixmapPtr pixmap;
};
+Bool xwl_present_entered_for_each_frame_callback(void);
void xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
void iter_func(struct xwl_present_window *));
void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index b80a7bf67..6b7f38605 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1226,8 +1226,16 @@ frame_callback(void *data,
xwl_window->frame_callback = NULL;
#ifdef GLAMOR_HAS_GBM
- if (xwl_window->xwl_screen->present)
+ if (xwl_window->xwl_screen->present) {
xwl_present_for_each_frame_callback(xwl_window, xwl_present_frame_callback);
+
+ /* If xwl_window_create_frame_callback was called from
+ * xwl_present_frame_callback, need to make sure all fallback timers
+ * are adjusted correspondingly.
+ */
+ if (xwl_window->frame_callback)
+ xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
+ }
#endif
}
@@ -1243,7 +1251,11 @@ xwl_window_create_frame_callback(struct xwl_window *xwl_window)
xwl_window);
#ifdef GLAMOR_HAS_GBM
- if (xwl_window->xwl_screen->present)
+ /* If we get called from frame_callback, it will take care of calling
+ * xwl_present_reset_timer.
+ */
+ if (xwl_window->xwl_screen->present &&
+ !xwl_present_entered_for_each_frame_callback())
xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
#endif
}
commit 4d1cd7cdc22013ed8de17d3218b9790b7027e1fe
Author: Michel Dänzer <mdaenzer at redhat.com>
Date: Thu Mar 9 18:44:25 2023 +0100
xwayland: Refactor xwl_present_for_each_frame_callback helper
Preparation for following changes, no functional change intended.
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 2c0e1a05c..e8a173774 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -89,6 +89,18 @@ xwl_present_event_from_id(uint64_t event_id)
return (struct xwl_present_event*)(uintptr_t)event_id;
}
+void
+xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
+ void iter_func(struct xwl_present_window *))
+{
+ struct xwl_present_window *xwl_present_window, *tmp;
+
+ xorg_list_for_each_entry_safe(xwl_present_window, tmp,
+ &xwl_window->frame_callback_list,
+ frame_callback_list)
+ iter_func(xwl_present_window);
+}
+
static void
xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
{
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index ab7f04a3b..620e6c5ca 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -61,6 +61,8 @@ struct xwl_present_event {
PixmapPtr pixmap;
};
+void xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
+ void iter_func(struct xwl_present_window *));
void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window);
void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
Bool xwl_present_init(ScreenPtr screen);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index e159743a0..b80a7bf67 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1090,15 +1090,8 @@ xwl_unrealize_window(WindowPtr window)
xwl_dmabuf_feedback_destroy(&xwl_window->feedback);
#ifdef GLAMOR_HAS_GBM
- if (xwl_screen->present) {
- struct xwl_present_window *xwl_present_window, *tmp;
-
- xorg_list_for_each_entry_safe(xwl_present_window, tmp,
- &xwl_window->frame_callback_list,
- frame_callback_list) {
- xwl_present_unrealize_window(xwl_present_window);
- }
- }
+ if (xwl_window->xwl_screen->present)
+ xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window);
#endif
release_wl_surface_for_window(xwl_window);
@@ -1233,15 +1226,8 @@ frame_callback(void *data,
xwl_window->frame_callback = NULL;
#ifdef GLAMOR_HAS_GBM
- if (xwl_window->xwl_screen->present) {
- struct xwl_present_window *xwl_present_window, *tmp;
-
- xorg_list_for_each_entry_safe(xwl_present_window, tmp,
- &xwl_window->frame_callback_list,
- frame_callback_list) {
- xwl_present_frame_callback(xwl_present_window);
- }
- }
+ if (xwl_window->xwl_screen->present)
+ xwl_present_for_each_frame_callback(xwl_window, xwl_present_frame_callback);
#endif
}
@@ -1257,15 +1243,8 @@ xwl_window_create_frame_callback(struct xwl_window *xwl_window)
xwl_window);
#ifdef GLAMOR_HAS_GBM
- if (xwl_window->xwl_screen->present) {
- struct xwl_present_window *xwl_present_window, *tmp;
-
- xorg_list_for_each_entry_safe(xwl_present_window, tmp,
- &xwl_window->frame_callback_list,
- frame_callback_list) {
- xwl_present_reset_timer(xwl_present_window);
- }
- }
+ if (xwl_window->xwl_screen->present)
+ xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
#endif
}
More information about the xorg-commit
mailing list