summaryrefslogtreecommitdiff
path: root/remoting
diff options
context:
space:
mode:
authorAntonio Borneo <antonio.borneo@st.com>2019-06-30 15:51:10 +0200
committerDaniel Stone <daniel@fooishbar.org>2019-07-12 17:16:52 +0000
commitc90fccc256ee4cb8d6a516695708bf0c3685c348 (patch)
tree76b0ed4c2ce5c584e97a88af9f0cbf231065e8e3 /remoting
parent9c81224eb36c845978106927f8eea71c3f2e0743 (diff)
downloadweston-c90fccc256ee4cb8d6a516695708bf0c3685c348.tar.gz
backend-drm: fix race during system suspend
Depending on system loading, weston-launcher could drop the drm master access before the compositor and all the clients receive the notification. In this case, some commit could be sent to the drm driver too late and get refused with error EACCES. This error condition is not properly managed and causes weston to hang. Change the return type of start_repaint_loop() and repaint_flush() from void to int, and return 0 on success or -1 if the repaint has to be cancelled. In the callers of start_repaint_loop() and repaint_flush() handle the return value and cancel the repaint when needed. In backend-drm detect the error EACCES and return -1. Note: to keep the code cleaner, this change inverts the execution order between weston_output_schedule_repaint_reset() and repaint_cancel(). No need to wait for suspend or for any notification; in case the weston reschedules a repaint, it will get EACCES again. At resume, damage-all guarantees a complete repaint. This fix is for atomic modeset only. Legacy modeset suffers from similar problems, but it is not fixed by this change. Since drm_pending_state_apply() never returns error for legacy modeset, this change has no impact on legacy modeset. Signed-off-by: Antonio Borneo <antonio.borneo@st.com> Fixes: https://gitlab.freedesktop.org/wayland/weston/issues/117
Diffstat (limited to 'remoting')
-rw-r--r--remoting/remoting-plugin.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/remoting/remoting-plugin.c b/remoting/remoting-plugin.c
index 7c9bbb11..753f206c 100644
--- a/remoting/remoting-plugin.c
+++ b/remoting/remoting-plugin.c
@@ -93,7 +93,7 @@ struct remoted_output {
void (*saved_destroy)(struct weston_output *output);
int (*saved_enable)(struct weston_output *output);
int (*saved_disable)(struct weston_output *output);
- void (*saved_start_repaint_loop)(struct weston_output *output);
+ int (*saved_start_repaint_loop)(struct weston_output *output);
char *host;
int port;
@@ -647,7 +647,7 @@ remoting_output_destroy(struct weston_output *output)
free(remoted_output);
}
-static void
+static int
remoting_output_start_repaint_loop(struct weston_output *output)
{
struct remoted_output *remoted_output = lookup_remoted_output(output);
@@ -658,6 +658,8 @@ remoting_output_start_repaint_loop(struct weston_output *output)
msec = millihz_to_nsec(remoted_output->output->current_mode->refresh)
/ 1000000;
wl_event_source_timer_update(remoted_output->finish_frame_timer, msec);
+
+ return 0;
}
static int