vulkan/queue: Check for _mem_signal_temp before we submit
vk_queue_push_submit() takes ownership of the vk_queue_submit object and
potentially passes it to another thread. This fixes a race where, if
the other thread processes and deletes the vk_queue_submit before we get
to checking _mem_signal_temp, we may have a use-after-free.
Fixes: c95b646e23 ("vulkan/queue: Use _mem_signal_temp instead of signal_mem_sync")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11988
Reviewed-by: Juan A. Suarez <jasuarez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31597>
This commit is contained in:
committed by
Marge Bot
parent
980d0e2d06
commit
f33e18ab39
@@ -1184,18 +1184,20 @@ vk_queue_submit(struct vk_queue *queue,
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're signaling a memory object, we have to ensure that
|
||||
* vkQueueSubmit does not return until the kernel submission has
|
||||
* happened. Otherwise, we may get a race between this process
|
||||
* and whatever is going to wait on the object where the other
|
||||
* process may wait before we've submitted our work. Drain the
|
||||
* queue now to avoid this. It's the responsibility of the caller
|
||||
* to ensure that any vkQueueSubmit which signals a memory object
|
||||
* has fully resolved dependencies.
|
||||
*/
|
||||
const bool needs_drain = submit->_mem_signal_temp;
|
||||
|
||||
vk_queue_push_submit(queue, submit);
|
||||
|
||||
if (submit->_mem_signal_temp != NULL) {
|
||||
/* If we're signaling a memory object, we have to ensure that
|
||||
* vkQueueSubmit does not return until the kernel submission has
|
||||
* happened. Otherwise, we may get a race between this process
|
||||
* and whatever is going to wait on the object where the other
|
||||
* process may wait before we've submitted our work. Drain the
|
||||
* queue now to avoid this. It's the responsibility of the caller
|
||||
* to ensure that any vkQueueSubmit which signals a memory object
|
||||
* has fully resolved dependencies.
|
||||
*/
|
||||
if (needs_drain) {
|
||||
result = vk_queue_drain(queue);
|
||||
if (unlikely(result != VK_SUCCESS))
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user