[mutter] renderer/native: fix next_fb_id race on CPU copy path



commit 85e9784a22df401dfb0350fe550f33be0e51b434
Author: Pekka Paalanen <pekka paalanen collabora co uk>
Date:   Thu Oct 4 13:53:17 2018 +0300

    renderer/native: fix next_fb_id race on CPU copy path
    
    There was a race in setting next_fb_id when a secondary GPU was using
    the CPU copy path. Losing this race caused the attempt to
    drmModePageFlip () to FB ID 0 which is invalid and always fails. Failing
    to flip causes Mutter to fall back to drmModeSetCrtc () permanently.
    
    In meta_onscreen_native_swap_buffers_with_damage ():
    - update_secondary_gpu_state_pre_swap_buffers ()
      - copy_shared_framebuffer_cpu () but only on the CPU copy path
        - secondary_gpu_state->gbm.next_fb_id is set
    - wait_for_pending_flips ()
      - Waits for any remaining page flip events and executes and destroys
        the related page flip closures.
        - on_crtc_flipped ()
          - meta_onscreen_native_swap_drm_fb ()
            - swap_secondary_drm_fb ()
              - secondary_gpu_state->gbm.next_fb_id = 0;
    - meta_onscreen_native_flip_crtcs ()
      - meta_onscreen_native_flip_crtc ()
        - meta_gpu_kms_flip_crtc () gets called with fb_id = 0
    
    This race was observed lost when running 'mutter --wayland' on a machine
    with two outputs on Intel and one output on DisplayLink USB dock, and
    wiggling around a weston-terminal window between the Intel and
    DisplayLink outputs. It took from a second to a minute to trigger. For
    testing with DisplayLink outputs Mutter also needed a patch to take the
    DisplayLink output into use, as it would have otherwise been ignored
    being a platform device rather than a PCI device.
    
    Fix this race by first waiting for pending flips and only then
    proceeding with the swap operations. This should be safe, because the
    pending flips could have completed already before entering
    meta_onscreen_native_swap_buffers_with_damage ().

 src/backends/native/meta-renderer-native.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
---
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index f58e6b3e0..96414f678 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1900,6 +1900,12 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
   CoglFrameInfo *frame_info;
   gboolean egl_context_changed = FALSE;
 
+  /*
+   * Wait for the flip callback before continuing, as we might have started the
+   * animation earlier due to the animation being driven by some other monitor.
+   */
+  wait_for_pending_flips (onscreen);
+
   frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
   frame_info->global_frame_counter = renderer_native->frame_counter;
 
@@ -1909,12 +1915,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
                                                     rectangles,
                                                     n_rectangles);
 
-  /*
-   * Wait for the flip callback before continuing, as we might have started the
-   * animation earlier due to the animation being driven by some other monitor.
-   */
-  wait_for_pending_flips (onscreen);
-
   renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
                                                          render_gpu);
   switch (renderer_gpu_data->mode)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]