anv: Drop unused sync_file and BO semaphore code

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9777>
This commit is contained in:
Jason Ekstrand 2021-03-23 13:58:34 -05:00 committed by Marge Bot
parent 3b363d5b55
commit d44ea09e61
4 changed files with 44 additions and 264 deletions

View file

@ -1978,7 +1978,6 @@ anv_queue_execbuf_locked(struct anv_queue *queue,
}
if (submit->fence_count > 0) {
assert(device->physical->has_syncobj);
if (device->has_thread_submit) {
execbuf.timeline_fences.fence_count = submit->fence_count;
execbuf.timeline_fences.handles_ptr = (uintptr_t)submit->fences;

View file

@ -820,7 +820,6 @@ anv_physical_device_try_create(struct anv_instance *instance,
device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC);
device->has_exec_capture = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CAPTURE);
device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE);
device->has_syncobj = true;
device->has_syncobj_wait = anv_gem_supports_syncobj_wait(fd);
device->has_syncobj_wait_available =
anv_gem_get_drm_cap(fd, DRM_CAP_SYNCOBJ_TIMELINE) != 0;

View file

@ -921,7 +921,6 @@ struct anv_physical_device {
bool has_exec_async;
bool has_exec_capture;
bool has_exec_fence;
bool has_syncobj;
bool has_syncobj_wait;
bool has_syncobj_wait_available;
bool has_context_priority;
@ -1036,11 +1035,6 @@ struct anv_queue_submit {
uint32_t temporary_semaphore_array_length;
struct anv_semaphore_impl * temporary_semaphores;
/* Semaphores to be signaled with a SYNC_FD. */
struct anv_semaphore ** sync_fd_semaphores;
uint32_t sync_fd_semaphore_count;
uint32_t sync_fd_semaphore_array_length;
/* Allocated only with non shareable timelines. */
union {
struct anv_timeline ** wait_timelines;
@ -3340,9 +3334,7 @@ struct anv_event {
enum anv_semaphore_type {
ANV_SEMAPHORE_TYPE_NONE = 0,
ANV_SEMAPHORE_TYPE_DUMMY,
ANV_SEMAPHORE_TYPE_BO,
ANV_SEMAPHORE_TYPE_WSI_BO,
ANV_SEMAPHORE_TYPE_SYNC_FILE,
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ,
ANV_SEMAPHORE_TYPE_TIMELINE,
ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ_TIMELINE,
@ -3385,12 +3377,6 @@ struct anv_semaphore_impl {
*/
struct anv_bo *bo;
/* The sync file descriptor when type == ANV_SEMAPHORE_TYPE_SYNC_FILE.
* If the semaphore is in the unsignaled state due to either just being
* created or because it has been used for a wait, fd will be -1.
*/
int fd;
/* Sync object handle when type == ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ.
* Unlike GEM BOs, DRM sync objects aren't deduplicated by the kernel on
* import so we don't need to bother with a userspace cache.

View file

@ -80,7 +80,6 @@ static int64_t anv_get_relative_timeout(uint64_t abs_timeout)
return rel_timeout;
}
static struct anv_semaphore *anv_semaphore_ref(struct anv_semaphore *semaphore);
static void anv_semaphore_unref(struct anv_device *device, struct anv_semaphore *semaphore);
static void anv_semaphore_impl_cleanup(struct anv_device *device,
struct anv_semaphore_impl *impl);
@ -93,8 +92,6 @@ anv_queue_submit_free(struct anv_device *device,
for (uint32_t i = 0; i < submit->temporary_semaphore_count; i++)
anv_semaphore_impl_cleanup(device, &submit->temporary_semaphores[i]);
for (uint32_t i = 0; i < submit->sync_fd_semaphore_count; i++)
anv_semaphore_unref(device, submit->sync_fd_semaphores[i]);
/* Execbuf does not consume the in_fence. It's our job to close it. */
if (submit->in_fence != -1) {
assert(!device->has_thread_submit);
@ -293,19 +290,6 @@ anv_queue_submit_timeline_locked(struct anv_queue *queue,
assert(signal_value > timeline->highest_pending);
timeline->highest_pending = signal_value;
}
/* Update signaled semaphores backed by syncfd. */
for (uint32_t i = 0; i < submit->sync_fd_semaphore_count; i++) {
struct anv_semaphore *semaphore = submit->sync_fd_semaphores[i];
/* Out fences can't have temporary state because that would imply
* that we imported a sync file and are trying to signal it.
*/
assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE);
struct anv_semaphore_impl *impl = &semaphore->permanent;
assert(impl->type == ANV_SEMAPHORE_TYPE_SYNC_FILE);
impl->fd = os_dupfd_cloexec(submit->out_fence);
}
} else {
/* Unblock any waiter by signaling the points, the application will get
* a device lost error code.
@ -425,18 +409,6 @@ anv_queue_task(void *_queue)
pthread_mutex_unlock(&queue->device->mutex);
}
for (uint32_t i = 0; i < submit->sync_fd_semaphore_count; i++) {
struct anv_semaphore *semaphore = submit->sync_fd_semaphores[i];
/* Out fences can't have temporary state because that would imply
* that we imported a sync file and are trying to signal it.
*/
assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE);
struct anv_semaphore_impl *impl = &semaphore->permanent;
assert(impl->type == ANV_SEMAPHORE_TYPE_SYNC_FILE);
impl->fd = dup(submit->out_fence);
}
if (result != VK_SUCCESS) {
/* vkQueueSubmit or some other entry point will report the
* DEVICE_LOST error at some point, but until we have emptied our
@ -664,29 +636,6 @@ anv_queue_submit_add_syncobj(struct anv_queue_submit* submit,
return VK_SUCCESS;
}
static VkResult
anv_queue_submit_add_sync_fd_fence(struct anv_queue_submit *submit,
struct anv_semaphore *semaphore)
{
if (submit->sync_fd_semaphore_count >= submit->sync_fd_semaphore_array_length) {
uint32_t new_len = MAX2(submit->sync_fd_semaphore_array_length * 2, 64);
struct anv_semaphore **new_semaphores =
vk_realloc(submit->alloc, submit->sync_fd_semaphores,
new_len * sizeof(*submit->sync_fd_semaphores), 8,
submit->alloc_scope);
if (new_semaphores == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
submit->sync_fd_semaphores = new_semaphores;
}
submit->sync_fd_semaphores[submit->sync_fd_semaphore_count++] =
anv_semaphore_ref(semaphore);
submit->need_out_fence = true;
return VK_SUCCESS;
}
static VkResult
anv_queue_submit_add_timeline_wait(struct anv_queue_submit* submit,
struct anv_device *device,
@ -938,7 +887,6 @@ anv_queue_submit_add_in_semaphores(struct anv_queue_submit *submit,
const uint64_t *in_values,
uint32_t num_in_semaphores)
{
ASSERTED struct anv_physical_device *pdevice = device->physical;
VkResult result;
for (uint32_t i = 0; i < num_in_semaphores; i++) {
@ -950,13 +898,6 @@ anv_queue_submit_add_in_semaphores(struct anv_queue_submit *submit,
return result;
switch (impl->type) {
case ANV_SEMAPHORE_TYPE_BO:
assert(!pdevice->has_syncobj);
result = anv_queue_submit_add_fence_bo(submit, impl->bo, false /* signal */);
if (result != VK_SUCCESS)
return result;
break;
case ANV_SEMAPHORE_TYPE_WSI_BO:
/* When using a window-system buffer as a semaphore, always enable
* EXEC_OBJECT_WRITE. This gives us a WaR hazard with the display or
@ -969,24 +910,6 @@ anv_queue_submit_add_in_semaphores(struct anv_queue_submit *submit,
return result;
break;
case ANV_SEMAPHORE_TYPE_SYNC_FILE:
assert(!pdevice->has_syncobj);
if (submit->in_fence == -1) {
submit->in_fence = impl->fd;
if (submit->in_fence == -1)
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
impl->fd = -1;
} else {
int merge = anv_gem_sync_file_merge(device, submit->in_fence, impl->fd);
if (merge == -1)
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
close(impl->fd);
close(submit->in_fence);
impl->fd = -1;
submit->in_fence = merge;
}
break;
case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ: {
result = anv_queue_submit_add_syncobj(submit, device,
impl->syncobj,
@ -1035,7 +958,6 @@ anv_queue_submit_add_out_semaphores(struct anv_queue_submit *submit,
const uint64_t *out_values,
uint32_t num_out_semaphores)
{
ASSERTED struct anv_physical_device *pdevice = device->physical;
VkResult result;
for (uint32_t i = 0; i < num_out_semaphores; i++) {
@ -1057,20 +979,6 @@ anv_queue_submit_add_out_semaphores(struct anv_queue_submit *submit,
&semaphore->temporary : &semaphore->permanent;
switch (impl->type) {
case ANV_SEMAPHORE_TYPE_BO:
assert(!pdevice->has_syncobj);
result = anv_queue_submit_add_fence_bo(submit, impl->bo, true /* signal */);
if (result != VK_SUCCESS)
return result;
break;
case ANV_SEMAPHORE_TYPE_SYNC_FILE:
assert(!pdevice->has_syncobj);
result = anv_queue_submit_add_sync_fd_fence(submit, semaphore);
if (result != VK_SUCCESS)
return result;
break;
case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ: {
/*
* Reset the content of the syncobj so it doesn't contain a
@ -1265,7 +1173,6 @@ anv_queue_submit_can_add_submit(const struct anv_queue_submit *submit,
/* We can add to an empty anv_queue_submit. */
if (submit->cmd_buffer_count == 0 &&
submit->fence_count == 0 &&
submit->sync_fd_semaphore_count == 0 &&
submit->wait_timeline_count == 0 &&
submit->signal_timeline_count == 0 &&
submit->fence_bo_count == 0)
@ -1276,8 +1183,7 @@ anv_queue_submit_can_add_submit(const struct anv_queue_submit *submit,
return false;
/* If the current submit is signaling anything, we can't add anything. */
if (submit->signal_timeline_count ||
submit->sync_fd_semaphore_count)
if (submit->signal_timeline_count)
return false;
/* If a submit is waiting on anything, anything that happened before needs
@ -2171,26 +2077,11 @@ binary_semaphore_create(struct anv_device *device,
struct anv_semaphore_impl *impl,
bool exportable)
{
if (device->physical->has_syncobj) {
impl->type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ;
impl->syncobj = anv_gem_syncobj_create(device, 0);
if (!impl->syncobj)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
return VK_SUCCESS;
} else {
impl->type = ANV_SEMAPHORE_TYPE_BO;
VkResult result =
anv_device_alloc_bo(device, "binary-semaphore", 4096,
ANV_BO_ALLOC_EXTERNAL |
ANV_BO_ALLOC_IMPLICIT_SYNC,
0 /* explicit_address */,
&impl->bo);
/* If we're going to use this as a fence, we need to *not* have the
* EXEC_OBJECT_ASYNC bit set.
*/
assert(!(impl->bo->flags & EXEC_OBJECT_ASYNC));
return result;
}
impl->type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ;
impl->syncobj = anv_gem_syncobj_create(device, 0);
if (!impl->syncobj)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
return VK_SUCCESS;
}
static VkResult
@ -2268,16 +2159,11 @@ VkResult anv_CreateSemaphore(
} else if (handleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
assert(handleTypes == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
assert(sem_type == VK_SEMAPHORE_TYPE_BINARY_KHR);
if (device->physical->has_syncobj) {
semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ;
semaphore->permanent.syncobj = anv_gem_syncobj_create(device, 0);
if (!semaphore->permanent.syncobj) {
vk_object_free(&device->vk, pAllocator, semaphore);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
} else {
semaphore->permanent.type = ANV_SEMAPHORE_TYPE_SYNC_FILE;
semaphore->permanent.fd = -1;
semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ;
semaphore->permanent.syncobj = anv_gem_syncobj_create(device, 0);
if (!semaphore->permanent.syncobj) {
vk_object_free(&device->vk, pAllocator, semaphore);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
} else {
assert(!"Unknown handle type");
@ -2302,16 +2188,10 @@ anv_semaphore_impl_cleanup(struct anv_device *device,
/* Dummy. Nothing to do */
break;
case ANV_SEMAPHORE_TYPE_BO:
case ANV_SEMAPHORE_TYPE_WSI_BO:
anv_device_release_bo(device, impl->bo);
break;
case ANV_SEMAPHORE_TYPE_SYNC_FILE:
if (impl->fd >= 0)
close(impl->fd);
break;
case ANV_SEMAPHORE_TYPE_TIMELINE:
anv_timeline_finish(device, &impl->timeline);
break;
@ -2338,14 +2218,6 @@ anv_semaphore_reset_temporary(struct anv_device *device,
anv_semaphore_impl_cleanup(device, &semaphore->temporary);
}
static struct anv_semaphore *
anv_semaphore_ref(struct anv_semaphore *semaphore)
{
assert(semaphore->refcount);
p_atomic_inc(&semaphore->refcount);
return semaphore;
}
static void
anv_semaphore_unref(struct anv_device *device, struct anv_semaphore *semaphore)
{
@ -2435,41 +2307,19 @@ VkResult anv_ImportSemaphoreFdKHR(
switch (pImportSemaphoreFdInfo->handleType) {
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
if (device->physical->has_syncobj) {
/* When importing non temporarily, reuse the semaphore's existing
* type. The Linux/DRM implementation allows to interchangeably use
* binary & timeline semaphores and we have no way to differenciate
* them.
*/
if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT)
new_impl.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ;
else
new_impl.type = semaphore->permanent.type;
/* When importing non temporarily, reuse the semaphore's existing
* type. The Linux/DRM implementation allows to interchangeably use
* binary & timeline semaphores and we have no way to differenciate
* them.
*/
if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT)
new_impl.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ;
else
new_impl.type = semaphore->permanent.type;
new_impl.syncobj = anv_gem_syncobj_fd_to_handle(device, fd);
if (!new_impl.syncobj)
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
} else {
new_impl.type = ANV_SEMAPHORE_TYPE_BO;
VkResult result = anv_device_import_bo(device, fd,
ANV_BO_ALLOC_EXTERNAL |
ANV_BO_ALLOC_IMPLICIT_SYNC,
0 /* client_address */,
&new_impl.bo);
if (result != VK_SUCCESS)
return result;
if (new_impl.bo->size < 4096) {
anv_device_release_bo(device, new_impl.bo);
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
}
/* If we're going to use this as a fence, we need to *not* have the
* EXEC_OBJECT_ASYNC bit set.
*/
assert(!(new_impl.bo->flags & EXEC_OBJECT_ASYNC));
}
new_impl.syncobj = anv_gem_syncobj_fd_to_handle(device, fd);
if (!new_impl.syncobj)
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
/* From the Vulkan spec:
*
@ -2483,40 +2333,34 @@ VkResult anv_ImportSemaphoreFdKHR(
close(fd);
break;
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
if (device->physical->has_syncobj) {
uint32_t create_flags = 0;
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: {
uint32_t create_flags = 0;
if (fd == -1)
create_flags |= DRM_SYNCOBJ_CREATE_SIGNALED;
if (fd == -1)
create_flags |= DRM_SYNCOBJ_CREATE_SIGNALED;
new_impl = (struct anv_semaphore_impl) {
.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ,
.syncobj = anv_gem_syncobj_create(device, create_flags),
};
new_impl = (struct anv_semaphore_impl) {
.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ,
.syncobj = anv_gem_syncobj_create(device, create_flags),
};
if (!new_impl.syncobj)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
if (!new_impl.syncobj)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
if (fd != -1) {
if (anv_gem_syncobj_import_sync_file(device, new_impl.syncobj, fd)) {
anv_gem_syncobj_destroy(device, new_impl.syncobj);
return vk_errorf(device, NULL, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"syncobj sync file import failed: %m");
}
/* Ownership of the FD is transfered to Anv. Since we don't need it
* anymore because the associated fence has been put into a syncobj,
* we must close the FD.
*/
close(fd);
if (fd != -1) {
if (anv_gem_syncobj_import_sync_file(device, new_impl.syncobj, fd)) {
anv_gem_syncobj_destroy(device, new_impl.syncobj);
return vk_errorf(device, NULL, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"syncobj sync file import failed: %m");
}
} else {
new_impl = (struct anv_semaphore_impl) {
.type = ANV_SEMAPHORE_TYPE_SYNC_FILE,
.fd = fd,
};
/* Ownership of the FD is transfered to Anv. Since we don't need it
* anymore because the associated fence has been put into a syncobj,
* we must close the FD.
*/
close(fd);
}
break;
}
default:
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
@ -2540,7 +2384,6 @@ VkResult anv_GetSemaphoreFdKHR(
{
ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_semaphore, semaphore, pGetFdInfo->semaphore);
VkResult result;
int fd;
assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR);
@ -2550,53 +2393,6 @@ VkResult anv_GetSemaphoreFdKHR(
&semaphore->temporary : &semaphore->permanent;
switch (impl->type) {
case ANV_SEMAPHORE_TYPE_BO:
result = anv_device_export_bo(device, impl->bo, pFd);
if (result != VK_SUCCESS)
return result;
break;
case ANV_SEMAPHORE_TYPE_SYNC_FILE: {
/* There's a potential race here with vkQueueSubmit if you are trying
* to export a semaphore Fd while the queue submit is still happening.
* This can happen if we see all dependencies get resolved via timeline
* semaphore waits completing before the execbuf completes and we
* process the resulting out fence. To work around this, take a lock
* around grabbing the fd.
*/
pthread_mutex_lock(&device->mutex);
/* From the Vulkan 1.0.53 spec:
*
* "...exporting a semaphore payload to a handle with copy
* transference has the same side effects on the source
* semaphores payload as executing a semaphore wait operation."
*
* In other words, it may still be a SYNC_FD semaphore, but it's now
* considered to have been waited on and no longer has a sync file
* attached.
*/
int fd = impl->fd;
impl->fd = -1;
pthread_mutex_unlock(&device->mutex);
/* There are two reasons why this could happen:
*
* 1) The user is trying to export without submitting something that
* signals the semaphore. If this is the case, it's their bug so
* what we return here doesn't matter.
*
* 2) The kernel didn't give us a file descriptor. The most likely
* reason for this is running out of file descriptors.
*/
if (fd < 0)
return vk_error(VK_ERROR_TOO_MANY_OBJECTS);
*pFd = fd;
return VK_SUCCESS;
}
case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ:
if (pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
VkResult result = wait_syncobj_materialize(device, impl->syncobj, pFd);