anv: prevent access to destroyed vk_sync objects post submission
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Fixes:36ea90a361
("anv: Convert to the common sync and submit framework") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/12145 Reviewed-by: Ivan Briano <ivan.briano@intel.com> (cherry picked from commit9b779068c3
) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32261>
This commit is contained in:

committed by
Dylan Baker

parent
faacd80403
commit
0bf0f66c9e
@@ -4,7 +4,7 @@
|
|||||||
"description": "anv: prevent access to destroyed vk_sync objects post submission",
|
"description": "anv: prevent access to destroyed vk_sync objects post submission",
|
||||||
"nominated": true,
|
"nominated": true,
|
||||||
"nomination_type": 2,
|
"nomination_type": 2,
|
||||||
"resolution": 0,
|
"resolution": 1,
|
||||||
"main_sha": null,
|
"main_sha": null,
|
||||||
"because_sha": "36ea90a3619f86e9bf0b51e2b0c28b213e08083d",
|
"because_sha": "36ea90a3619f86e9bf0b51e2b0c28b213e08083d",
|
||||||
"notes": null
|
"notes": null
|
||||||
|
@@ -1478,6 +1478,24 @@ anv_queue_submit_cmd_buffers_locked(struct anv_queue *queue,
|
|||||||
{
|
{
|
||||||
VkResult result;
|
VkResult result;
|
||||||
|
|
||||||
|
/* It's not safe to access submit->signals[] elements after submit because
|
||||||
|
* the elements might signal through the kernel before this function
|
||||||
|
* returns and another thread could wake up and destroy any of those
|
||||||
|
* elements.
|
||||||
|
*
|
||||||
|
* Build a list of anv_bo_sync elements here and put them in the signal
|
||||||
|
* state after without looking at any other element.
|
||||||
|
*/
|
||||||
|
STACK_ARRAY(struct anv_bo_sync *, bo_signals, submit->signal_count);
|
||||||
|
uint32_t bo_signal_count = 0;
|
||||||
|
for (uint32_t i = 0; i < submit->signal_count; i++) {
|
||||||
|
if (!vk_sync_is_anv_bo_sync(submit->signals[i].sync))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bo_signals[bo_signal_count++] =
|
||||||
|
container_of(submit->signals[i].sync, struct anv_bo_sync, sync);
|
||||||
|
}
|
||||||
|
|
||||||
if (submit->command_buffer_count == 0) {
|
if (submit->command_buffer_count == 0) {
|
||||||
result = anv_queue_exec_locked(queue, submit->wait_count, submit->waits,
|
result = anv_queue_exec_locked(queue, submit->wait_count, submit->waits,
|
||||||
0 /* cmd_buffer_count */,
|
0 /* cmd_buffer_count */,
|
||||||
@@ -1487,7 +1505,7 @@ anv_queue_submit_cmd_buffers_locked(struct anv_queue *queue,
|
|||||||
0 /* perf_query_pass */,
|
0 /* perf_query_pass */,
|
||||||
utrace_submit);
|
utrace_submit);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
return result;
|
goto fail;
|
||||||
} else {
|
} else {
|
||||||
/* Everything's easier if we don't have to bother with container_of() */
|
/* Everything's easier if we don't have to bother with container_of() */
|
||||||
STATIC_ASSERT(offsetof(struct anv_cmd_buffer, vk) == 0);
|
STATIC_ASSERT(offsetof(struct anv_cmd_buffer, vk) == 0);
|
||||||
@@ -1515,7 +1533,7 @@ anv_queue_submit_cmd_buffers_locked(struct anv_queue *queue,
|
|||||||
/* The next buffer cannot be chained, or we have reached the
|
/* The next buffer cannot be chained, or we have reached the
|
||||||
* last buffer, submit what have been chained so far.
|
* last buffer, submit what have been chained so far.
|
||||||
*/
|
*/
|
||||||
VkResult result =
|
result =
|
||||||
anv_queue_exec_locked(queue,
|
anv_queue_exec_locked(queue,
|
||||||
start == 0 ? submit->wait_count : 0,
|
start == 0 ? submit->wait_count : 0,
|
||||||
start == 0 ? submit->waits : NULL,
|
start == 0 ? submit->waits : NULL,
|
||||||
@@ -1526,7 +1544,7 @@ anv_queue_submit_cmd_buffers_locked(struct anv_queue *queue,
|
|||||||
submit->perf_pass_index,
|
submit->perf_pass_index,
|
||||||
next == end ? utrace_submit : NULL);
|
next == end ? utrace_submit : NULL);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
return result;
|
goto fail;
|
||||||
if (next < end) {
|
if (next < end) {
|
||||||
start = next;
|
start = next;
|
||||||
perf_query_pool = cmd_buffers[start]->perf_query_pool;
|
perf_query_pool = cmd_buffers[start]->perf_query_pool;
|
||||||
@@ -1534,12 +1552,8 @@ anv_queue_submit_cmd_buffers_locked(struct anv_queue *queue,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < submit->signal_count; i++) {
|
for (uint32_t i = 0; i < bo_signal_count; i++) {
|
||||||
if (!vk_sync_is_anv_bo_sync(submit->signals[i].sync))
|
struct anv_bo_sync *bo_sync = bo_signals[i];
|
||||||
continue;
|
|
||||||
|
|
||||||
struct anv_bo_sync *bo_sync =
|
|
||||||
container_of(submit->signals[i].sync, struct anv_bo_sync, sync);
|
|
||||||
|
|
||||||
/* Once the execbuf has returned, we need to set the fence state to
|
/* Once the execbuf has returned, we need to set the fence state to
|
||||||
* SUBMITTED. We can't do this before calling execbuf because
|
* SUBMITTED. We can't do this before calling execbuf because
|
||||||
@@ -1557,7 +1571,9 @@ anv_queue_submit_cmd_buffers_locked(struct anv_queue *queue,
|
|||||||
|
|
||||||
pthread_cond_broadcast(&queue->device->queue_submit);
|
pthread_cond_broadcast(&queue->device->queue_submit);
|
||||||
|
|
||||||
return VK_SUCCESS;
|
fail:
|
||||||
|
STACK_ARRAY_FINISH(bo_signals);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
Reference in New Issue
Block a user