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 <post@arntzen-software.no>
Reviewed-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit 32f7ff2c20)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22637>
This commit is contained in:
Hans-Kristian Arntzen 2023-04-21 17:22:47 +02:00 committed by Eric Engestrom
parent 72d01ab287
commit 5db4186d97
2 changed files with 9 additions and 3 deletions

View file

@ -265,7 +265,7 @@
"description": "wsi/x11: Fix present ID signal when IDLE comes before COMPLETE.",
"nominated": false,
"nomination_type": null,
"resolution": 4,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View file

@ -1008,6 +1008,7 @@ struct x11_image {
int shmid;
uint8_t * shmaddr;
uint64_t present_id;
uint64_t signal_present_id;
};
struct x11_swapchain {
@ -1079,8 +1080,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);
@ -1104,6 +1105,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)