Module: Mesa Branch: staging/23.0 Commit: b0489e6221d2daa2a9ff431d777706549dff6a71 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b0489e6221d2daa2a9ff431d777706549dff6a71
Author: Hans-Kristian Arntzen <[email protected]> Date: Fri Apr 21 17:22:47 2023 +0200 wsi/x11: Fix present ID signal when IDLE comes before COMPLETE. It appears to be possible that IDLE is observed before COMPLETE. In this case, an application may access present_id in subsequent QueuePresentKHR and race against the fence worker reading present_id. Solve this by adding a separate signal_present_id that is used when completing to avoid the race. Signed-off-by: Hans-Kristian Arntzen <[email protected]> Reviewed-by: Adam Jackson <[email protected]> (cherry picked from commit 32f7ff2c204b28e6d312ecac6463f588d4d68f3e) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22638> --- src/vulkan/wsi/wsi_common_x11.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 16b0c34b7e7..9d466e73f39 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -939,6 +939,7 @@ struct x11_image { int shmid; uint8_t * shmaddr; uint64_t present_id; + uint64_t signal_present_id; }; struct x11_swapchain { @@ -1010,8 +1011,8 @@ static void x11_present_complete(struct x11_swapchain *swapchain, { if (image->present_id) { pthread_mutex_lock(&swapchain->present_progress_mutex); - if (image->present_id > swapchain->present_id) { - swapchain->present_id = image->present_id; + if (image->signal_present_id > swapchain->present_id) { + swapchain->present_id = image->signal_present_id; pthread_cond_broadcast(&swapchain->present_progress_cond); } pthread_mutex_unlock(&swapchain->present_progress_mutex); @@ -1035,6 +1036,11 @@ static void x11_notify_pending_present(struct x11_swapchain *swapchain, pthread_cond_broadcast(&swapchain->present_progress_cond); pthread_mutex_unlock(&swapchain->present_progress_mutex); } + + /* It is possible that an IDLE is observed before PRESENT_COMPLETE when + * not flipping. In this case, reading image->present_id might be a race + * in the FIFO management thread. */ + image->signal_present_id = image->present_id; } static void x11_swapchain_notify_error(struct x11_swapchain *swapchain, VkResult result)
